greprag 5.84.0 → 5.85.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/dist/hook.js CHANGED
@@ -141,8 +141,8 @@ const procedure_shadow_1 = require("./procedure-shadow");
141
141
  const inline_atom_hook_1 = require("./inline-atom-hook");
142
142
  const inline_atom_background_1 = require("./inline-atom-background");
143
143
  const reminder_injector_1 = require("./reminder-injector");
144
- const skill_landing_1 = require("./skill-landing");
145
- const skill_mirror_client_1 = require("./skill-mirror-client");
144
+ const skill_git_ingest_1 = require("./skill-git-ingest");
145
+ const agents_1 = require("./commands/agents");
146
146
  const repodoc_client_1 = require("./repodoc-client");
147
147
  const native_skill_pending_1 = require("./native-skill-pending");
148
148
  const doc_mirror_client_1 = require("./doc-mirror-client");
@@ -851,41 +851,6 @@ async function fetchEnrichmentDown(apiUrl, apiKey) {
851
851
  return null;
852
852
  }
853
853
  }
854
- /** SessionStart pass: the Skill Learning Loop's LANDING leg
855
- * (docs/skill-learning-loop.md — the write-back is CODE, not agent
856
- * voluntarism). Fetch pending gains → auto-land reference-tier into each
857
- * skill's docs/learnings.md → POST landed statuses back → return the report
858
- * for the announce. Undefined on any error → announce silent, gains stay
859
- * pending for the next session start. */
860
- async function fetchAndLandSkillGains(apiUrl, apiKey, anchor, cwd) {
861
- try {
862
- const res = await fetch(`${apiUrl}/v1/skillgain/${anchor.projectId}/pending`, {
863
- headers: { 'Authorization': `Bearer ${apiKey}` },
864
- });
865
- if (!res.ok)
866
- return undefined;
867
- const data = await res.json();
868
- const pending = (data.gains || []).filter(g => g.nodeId && g.skill && g.text);
869
- if (pending.length === 0)
870
- return undefined;
871
- const homeDir = process.env.HOME || process.env.USERPROFILE || '';
872
- const { report, statusUpdates } = (0, skill_landing_1.landPendingGains)(pending, cwd, homeDir, anchor.projectName);
873
- if (statusUpdates.length > 0) {
874
- try {
875
- await fetch(`${apiUrl}/v1/skillgain/${anchor.projectId}/status`, {
876
- method: 'POST',
877
- headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
878
- body: JSON.stringify({ projectName: anchor.projectName, updates: statusUpdates }),
879
- });
880
- }
881
- catch { /* statuses re-sync next start — the stamp keeps lands idempotent */ }
882
- }
883
- return report.landed.length > 0 ? report : undefined;
884
- }
885
- catch {
886
- return undefined;
887
- }
888
- }
889
854
  /** Manifest-liveness policy — mirror of core's assessLiveness threshold (the CLI
890
855
  * is a zero-dep artifact, so the tiny policy is duplicated, like
891
856
  * DOCPTR_ANNOUNCE_LIMIT). A doc must cite ≥3 in-repo paths with ≥60% dead before
@@ -1156,19 +1121,6 @@ async function store(input, source = 'claude-code') {
1156
1121
  }
1157
1122
  catch { /* fail-open — an inline-atom miss never fails the Stop hook */ }
1158
1123
  }
1159
- // Skill mirror (docs/load-system.md Tier 3): a skill-load turn shadows that
1160
- // skill's current markdown into the tenant's load store — upload ONLY on
1161
- // change (local hash state), so an unchanged skill costs zero network.
1162
- // Follower semantics: files stay canonical. Best-effort, never throws.
1163
- if (provenance === 'skill-injection') {
1164
- const mirrorSkill = (0, turn_provenance_1.provenanceHint)(provenance, turn.userPrompt);
1165
- if (mirrorSkill) {
1166
- await (0, skill_mirror_client_1.maybeMirrorSkill)({
1167
- skill: mirrorSkill, cwd, apiUrl: cfg.apiUrl, apiKey: cfg.apiKey,
1168
- sessionId: input.session_id,
1169
- });
1170
- }
1171
- }
1172
1124
  // Repo chunk index (adr/node-identity-port.md): the chunks are DERIVED from a
1173
1125
  // document plus the node graph committed beside it, so they are rebuilt when
1174
1126
  // the document moves rather than when someone remembers to run a push. Same
@@ -1603,10 +1555,9 @@ async function recap(input, mode = 'plain', opts = {}) {
1603
1555
  // Enrichment-health signal (fix c2eb8777) — the live Gemini probe verdict.
1604
1556
  // Null when healthy or unreachable; a positive failure fires the outage announce.
1605
1557
  const enrichmentDownPromise = fetchEnrichmentDown(cfg.apiUrl, cfg.apiKey);
1606
- // Skill Learning Loop landing leg (docs/skill-learning-loop.md): pending
1607
- // gains → auto-land references into learnings docs, hold rule/scope
1608
- // proposals for the announce. Best-effort; undefined → announce silent.
1609
- const skillGainsPromise = fetchAndLandSkillGains(cfg.apiUrl, cfg.apiKey, anchor, cwd);
1558
+ // The Skill Learning Loop no longer lands gains into skill folders: git owns
1559
+ // skills and GrepRAG never edits their content (adr/skill-ownership-git.md).
1560
+ const skillGainsPromise = Promise.resolve(undefined);
1610
1561
  // Tier-3 skill activation manifest (docs/load-system.md): fetch canonical
1611
1562
  // full descriptions, then omit skills this harness already advertises
1612
1563
  // natively. Best-effort; the renderer remains pure. The same roster is what
@@ -1614,6 +1565,20 @@ async function recap(input, mode = 'plain', opts = {}) {
1614
1565
  // extra round trip unless one is stale. adr: adr/skill-bundle-shape.md
1615
1566
  const mirroredSkillsPromise = (async () => {
1616
1567
  try {
1568
+ // Git owns skills: ingest what is committed before reading the roster,
1569
+ // so launchers and the manifest see the committed content. Cheap when
1570
+ // nothing changed (one git ls-tree per source).
1571
+ // adr: adr/skill-ownership-git.md
1572
+ try {
1573
+ const sources = (0, skill_git_ingest_1.gitSkillSources)(cwd);
1574
+ const projectId = sources.find(source => source.scope === 'project')?.projectId;
1575
+ const mirrorHashes = await (0, skill_git_ingest_1.fetchMirrorHashes)(cfg.apiUrl, cfg.apiKey, projectId);
1576
+ await (0, skill_git_ingest_1.ingestCommittedSkills)({
1577
+ apiUrl: cfg.apiUrl, apiKey: cfg.apiKey, sources, mirrorHashes,
1578
+ harness: platform, sessionId: input.session_id,
1579
+ });
1580
+ }
1581
+ catch { /* best effort: the next session start retries */ }
1617
1582
  const params = new URLSearchParams({ scope: 'effective', projectId: anchor.projectId });
1618
1583
  const res = await fetch(`${cfg.apiUrl}/v1/skillmirror?${params.toString()}`, {
1619
1584
  headers: { 'Authorization': `Bearer ${cfg.apiKey}` },
@@ -1636,6 +1601,16 @@ async function recap(input, mode = 'plain', opts = {}) {
1636
1601
  return undefined;
1637
1602
  }
1638
1603
  })();
1604
+ // The Codex/OpenCode AGENTS.md files follow ~/.claude/CLAUDE.md, the git
1605
+ // source, and GrepRAG's read-only copy follows its last commit.
1606
+ // adr: adr/skill-ownership-git.md
1607
+ const instructionsPromise = (async () => {
1608
+ try {
1609
+ (0, agents_1.renderGlobalInstructions)();
1610
+ await (0, agents_1.mirrorCommittedInstructions)({ apiUrl: cfg.apiUrl, apiKey: cfg.apiKey });
1611
+ }
1612
+ catch { /* best effort: the next session start retries */ }
1613
+ })();
1639
1614
  // Equipped-loadouts signal (docs/loadout.md §activation model): the recipient's
1640
1615
  // self-inflating skill bundles. SessionStart fetch → the ONE advisor announce
1641
1616
  // line each; ALSO cached locally so the per-turn Match sensor reads it without
@@ -1727,6 +1702,7 @@ async function recap(input, mode = 'plain', opts = {}) {
1727
1702
  updateAvailablePromise,
1728
1703
  bodyPromise,
1729
1704
  ]);
1705
+ await instructionsPromise;
1730
1706
  const equippedLoadouts = loadoutState.decls;
1731
1707
  // Loadout version-gate deficiency (docs/loadout.md §Version gating step 3): a
1732
1708
  // pending loadout whose equip floor is ABOVE the installed CLI version can't be