0xray 4.0.29 → 4.0.31
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/.grok-plugin/plugin.json +1 -1
- package/.opencode/skills/orchestrator/SKILL.md +12 -0
- package/.xray/features.json +1 -1
- package/README.md +1 -0
- package/dist/CHANGELOG.md +17 -0
- package/dist/README.md +1 -0
- package/dist/cli/commands/validate.js +5 -0
- package/dist/cli/index.js +16 -1
- package/dist/integrations/grok/hooks/grok-hook-utils.js +24 -4
- package/dist/integrations/grok/hooks/post-tool-use.js +2 -1
- package/dist/integrations/grok/hooks/pre-tool-use.js +90 -5
- package/dist/integrations/grok/hooks/session-start.js +7 -2
- package/dist/integrations/hooks/goggles-pipeline.mjs +568 -0
- package/dist/integrations/hooks/goggles-planes.json +28 -0
- package/dist/integrations/hooks/plates.cjs +23 -0
- package/dist/integrations/hooks/station-hook-runtime.cjs +40 -11
- package/dist/integrations/hooks/station-memory-ingest.mjs +3 -0
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/mcps/orchestrator/config/agent-capabilities.js +7 -0
- package/dist/memory-routing/plates.d.ts +1 -1
- package/dist/memory-routing/plates.js +5 -0
- package/dist/memory-routing/provider-loader.js +2 -0
- package/dist/nucleus/thin-dispatch.d.ts +1 -0
- package/dist/nucleus/thin-dispatch.js +4 -2
- package/dist/skills/orchestrator/SKILL.md +12 -0
- package/docs-site/docs/plates/glossary.md +27 -0
- package/docs-site/docs/plates/goggles.md +18 -0
- package/docs-site/docs/plates/grokbot.md +41 -0
- package/docs-site/docs/plates/host-pack.md +32 -0
- package/docs-site/docs/plates/house.md +42 -39
- package/docs-site/docs/plates/index.md +13 -1
- package/docs-site/docs/plates/kits.md +28 -0
- package/docs-site/docs/plates/suit.md +40 -0
- package/llms.txt +1 -0
- package/package.json +2 -2
- package/scripts/foundry/assert-packed-dist-cli.mjs +5 -0
- package/scripts/node/consumer-install-smoke.mjs +5 -0
- package/scripts/node/install-bridges.cjs +120 -12
- package/scripts/node/setup.cjs +80 -71
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/src/mcps/orchestrator/config/agent-capabilities.ts +8 -0
- package/src/skills/orchestrator/SKILL.md +12 -0
- package/vendor/@0xray/repertoire/dist/paths.js +4 -0
- package/xray/features.json +1 -1
|
@@ -1615,11 +1615,11 @@ function userBytesBeforeWear(previousText) {
|
|
|
1615
1615
|
return stripOwnedHookEntries(previousText);
|
|
1616
1616
|
}
|
|
1617
1617
|
|
|
1618
|
-
function
|
|
1618
|
+
function classifyCursorWearGit(targetDir) {
|
|
1619
1619
|
try {
|
|
1620
1620
|
execFileSync("git", ["--version"], { stdio: "ignore" });
|
|
1621
1621
|
} catch {
|
|
1622
|
-
|
|
1622
|
+
return "missing";
|
|
1623
1623
|
}
|
|
1624
1624
|
let bare = "";
|
|
1625
1625
|
try {
|
|
@@ -1629,9 +1629,9 @@ function assertCursorWearGit(targetDir) {
|
|
|
1629
1629
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1630
1630
|
}).trim();
|
|
1631
1631
|
} catch {
|
|
1632
|
-
|
|
1632
|
+
return "not-work-tree";
|
|
1633
1633
|
}
|
|
1634
|
-
if (bare === "true")
|
|
1634
|
+
if (bare === "true") return "bare";
|
|
1635
1635
|
let inside = "";
|
|
1636
1636
|
try {
|
|
1637
1637
|
inside = execFileSync("git", ["rev-parse", "--is-inside-work-tree"], {
|
|
@@ -1640,9 +1640,98 @@ function assertCursorWearGit(targetDir) {
|
|
|
1640
1640
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1641
1641
|
}).trim();
|
|
1642
1642
|
} catch {
|
|
1643
|
-
|
|
1643
|
+
return "not-work-tree";
|
|
1644
|
+
}
|
|
1645
|
+
if (inside !== "true") return "not-work-tree";
|
|
1646
|
+
return "ok";
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
function assertCursorWearGit(targetDir) {
|
|
1650
|
+
const kind = classifyCursorWearGit(targetDir);
|
|
1651
|
+
if (kind === "missing") throw new Error("cursor-wear: git is missing");
|
|
1652
|
+
if (kind === "bare") throw new Error("cursor-wear: bare repository");
|
|
1653
|
+
if (kind === "not-work-tree") throw new Error("cursor-wear: not a git work tree");
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
const CURSOR_HOOKS_SKIPPED_LINE =
|
|
1657
|
+
"cursor-wear: hooks skipped because this folder is not a git checkout\n";
|
|
1658
|
+
|
|
1659
|
+
function syncSetupSkillsAndRootLinks(packageRoot, targetDir) {
|
|
1660
|
+
require("./setup.cjs").syncSetupSkillsAndRootLinks(packageRoot, targetDir);
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
function setupSkillMirrorNames(packageRoot) {
|
|
1664
|
+
const skillsSource = fs.existsSync(path.join(packageRoot, "src", "skills"))
|
|
1665
|
+
? path.join(packageRoot, "src", "skills")
|
|
1666
|
+
: path.join(packageRoot, "dist", "skills");
|
|
1667
|
+
if (!fs.existsSync(skillsSource)) return new Set();
|
|
1668
|
+
const names = new Set();
|
|
1669
|
+
for (const entry of fs.readdirSync(skillsSource, { withFileTypes: true })) {
|
|
1670
|
+
if (!entry.isDirectory()) continue;
|
|
1671
|
+
if (fs.existsSync(path.join(skillsSource, entry.name, "SKILL.md"))) names.add(entry.name);
|
|
1644
1672
|
}
|
|
1645
|
-
|
|
1673
|
+
return names;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
/** The 4.0.28 skill mirror is not a consumer costume. Any other extra name still throws. */
|
|
1677
|
+
function isSetupSkillMirrorDump(err, packageRoot) {
|
|
1678
|
+
if (!err || err.code !== "FOUNDRY_COSTUME_DUMP") return false;
|
|
1679
|
+
if (!Array.isArray(err.extraSkills) || err.extraSkills.length === 0) return false;
|
|
1680
|
+
if (Array.isArray(err.extraAgents) && err.extraAgents.length > 0) return false;
|
|
1681
|
+
const mirrored = setupSkillMirrorNames(packageRoot);
|
|
1682
|
+
return err.extraSkills.every((name) => mirrored.has(name));
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
function packageShipsConsumerSuit(packageRoot) {
|
|
1686
|
+
return fs.existsSync(path.join(packageRoot, "AGENTS-consumer.md"));
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
/**
|
|
1690
|
+
* 4.0.28 consumer postinstall files: AGENTS.md, .gitignore, repertoire link,
|
|
1691
|
+
* .xray config, bridges, mill plant, then the setup.cjs skill mirror and
|
|
1692
|
+
* dist/scripts links. Does not install Cursor hooks or git hooks.
|
|
1693
|
+
* Existing user files follow the 4.0.28 guards inside those functions.
|
|
1694
|
+
*/
|
|
1695
|
+
function installConsumerProjectFiles(packageRoot, targetDir, log) {
|
|
1696
|
+
const write = typeof log === "function" ? log : () => {};
|
|
1697
|
+
if (!isConsumerInstall(packageRoot, targetDir) || !packageShipsConsumerSuit(packageRoot)) {
|
|
1698
|
+
return false;
|
|
1699
|
+
}
|
|
1700
|
+
const { deployManagedAgents } = require("./postinstall.cjs");
|
|
1701
|
+
const { applyConsumerGitignore } = require("./consumer-gitignore.cjs");
|
|
1702
|
+
const { mintConsumerSuit } = require("../foundry/mint-suit.cjs");
|
|
1703
|
+
deployManagedAgents(packageRoot, targetDir, write);
|
|
1704
|
+
applyConsumerGitignore(targetDir, packageRoot);
|
|
1705
|
+
wearVendoredRepertoire(packageRoot, targetDir, write);
|
|
1706
|
+
deployXrayConfig(targetDir, packageRoot, write);
|
|
1707
|
+
deployProjectMcpJson(targetDir, write);
|
|
1708
|
+
mergeOpencodeJson(targetDir, packageRoot, write);
|
|
1709
|
+
installOpencodeBridge(targetDir, packageRoot, write);
|
|
1710
|
+
installGrokBridge(targetDir, packageRoot, write);
|
|
1711
|
+
installHermesBridge(targetDir, packageRoot, write);
|
|
1712
|
+
installOpenclawBridge(targetDir, packageRoot, write);
|
|
1713
|
+
try {
|
|
1714
|
+
mintConsumerSuit(packageRoot, targetDir, write);
|
|
1715
|
+
} catch (err) {
|
|
1716
|
+
if (!isSetupSkillMirrorDump(err, packageRoot)) throw err;
|
|
1717
|
+
}
|
|
1718
|
+
syncSetupSkillsAndRootLinks(packageRoot, targetDir);
|
|
1719
|
+
return true;
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
/**
|
|
1723
|
+
* 4.0.28 consumer postinstall, minus Cursor hooks and git hooks.
|
|
1724
|
+
* Used only when the folder is not a git work tree.
|
|
1725
|
+
*/
|
|
1726
|
+
function wearSuitSkippingCursorHooks(packageRoot, targetDir, log) {
|
|
1727
|
+
const write = typeof log === "function" ? log : () => {};
|
|
1728
|
+
if (!installConsumerProjectFiles(packageRoot, targetDir, write)) {
|
|
1729
|
+
if (!isConsumerInstall(packageRoot, targetDir)) {
|
|
1730
|
+
wearVendoredRepertoire(packageRoot, targetDir, write);
|
|
1731
|
+
}
|
|
1732
|
+
syncSetupSkillsAndRootLinks(packageRoot, targetDir);
|
|
1733
|
+
}
|
|
1734
|
+
process.stderr.write(CURSOR_HOOKS_SKIPPED_LINE);
|
|
1646
1735
|
}
|
|
1647
1736
|
|
|
1648
1737
|
function isGitTracked(targetDir, rel) {
|
|
@@ -1794,7 +1883,16 @@ function wearCursorHooks(targetDir, packageRoot, log, opts) {
|
|
|
1794
1883
|
const options = opts || {};
|
|
1795
1884
|
const resolvedTarget = path.resolve(targetDir);
|
|
1796
1885
|
const resolvedPackage = path.resolve(packageRoot);
|
|
1886
|
+
if (classifyCursorWearGit(resolvedTarget) === "not-work-tree") {
|
|
1887
|
+
wearSuitSkippingCursorHooks(resolvedPackage, resolvedTarget, write);
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1797
1890
|
assertCursorWearGit(resolvedTarget);
|
|
1891
|
+
if (options.suit !== false) {
|
|
1892
|
+
if (!installConsumerProjectFiles(resolvedPackage, resolvedTarget, write)) {
|
|
1893
|
+
syncSetupSkillsAndRootLinks(resolvedPackage, resolvedTarget);
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1798
1896
|
if (!isConsumerInstall(resolvedPackage, resolvedTarget) || !consumerDistHooksReady(resolvedPackage)) {
|
|
1799
1897
|
return fastenCursorHooksAt(resolvedTarget, resolvedPackage, write);
|
|
1800
1898
|
}
|
|
@@ -1826,11 +1924,14 @@ function wearCursorHooks(targetDir, packageRoot, log, opts) {
|
|
|
1826
1924
|
snap.meta.also = linkedWearRoots(resolvedTarget);
|
|
1827
1925
|
saveWearState(snap.paths, snap.meta);
|
|
1828
1926
|
for (const extra of snap.meta.also) {
|
|
1829
|
-
wearCursorHooks(extra, resolvedPackage, write, { outerRoots: false });
|
|
1927
|
+
wearCursorHooks(extra, resolvedPackage, write, { outerRoots: false, suit: false });
|
|
1830
1928
|
process.stdout.write(`cursor-wear: wrote outer hooks at ${extra}\n`);
|
|
1831
1929
|
}
|
|
1832
1930
|
saveWearState(snap.paths, snap.meta);
|
|
1833
1931
|
}
|
|
1932
|
+
if (options.suit !== false && packageShipsConsumerSuit(resolvedPackage)) {
|
|
1933
|
+
fastenCursorHookScripts(resolvedTarget, resolvedPackage, write);
|
|
1934
|
+
}
|
|
1834
1935
|
write("cursor-bridge", "hooks.json wired to installed dist", "info", { path: hooksPath });
|
|
1835
1936
|
return hooksPath;
|
|
1836
1937
|
}
|
|
@@ -1959,12 +2060,19 @@ function setupProjectBridges(opts) {
|
|
|
1959
2060
|
: () => {
|
|
1960
2061
|
/* noop */
|
|
1961
2062
|
};
|
|
2063
|
+
if (classifyCursorWearGit(targetDir) === "not-work-tree") {
|
|
2064
|
+
wearSuitSkippingCursorHooks(packageRoot, targetDir, log);
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
1962
2067
|
assertSetupGit(targetDir);
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
2068
|
+
if (!installConsumerProjectFiles(packageRoot, targetDir, log)) {
|
|
2069
|
+
syncSetupSkillsAndRootLinks(packageRoot, targetDir);
|
|
2070
|
+
deployProjectMcpJson(targetDir, log);
|
|
2071
|
+
installOpencodeBridge(targetDir, packageRoot, log);
|
|
2072
|
+
installGrokBridge(targetDir, packageRoot, log);
|
|
2073
|
+
installHermesBridge(targetDir, packageRoot, log);
|
|
2074
|
+
installOpenclawBridge(targetDir, packageRoot, log);
|
|
2075
|
+
}
|
|
1968
2076
|
if (opts.gitHooks === true) installGitHooks(packageRoot, log, targetDir);
|
|
1969
2077
|
}
|
|
1970
2078
|
|
package/scripts/node/setup.cjs
CHANGED
|
@@ -3,6 +3,84 @@
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
|
|
6
|
+
function syncSetupSkillsAndRootLinks(packageRoot, targetDir) {
|
|
7
|
+
/* 1. Sync core skills from src/skills/ (dev) or dist/skills/ (consumer) → .opencode/skills/ [P3-SKILLS-DE-DUP-SCOPE-AND-EXEC-01: orchestrator package SSOT canonical src/skills/orchestrator/SKILL.md; mirror .opencode/skills/orchestrator/ is built output of this logic; see paired guarded fw in status.ts getSkillsList + mapping append + deep ref 2026-05-26 authority for one-package dedup under pivoted surgical plan]
|
|
8
|
+
[P3-SKILLS-DE-DUP-RESEARCHER-FOLLOW-01: researcher package SSOT canonical src/skills/researcher/SKILL.md (high-value per deep ref + YML precedent + playbook P3-SKILLS-FOLLOW-01); mirror .opencode/skills/researcher/ is built output of this logic; see paired guarded fw in status.ts + rich append + YML @ harness-codex verification (FORCE exercised P3-YML + codex-enforcement + 100/60/0 + 3 subagents tracked + 0 hot + 3-hot re-establish + all prior green) + deep ref 2026-05-26 + Phase 3 Pivot + Term 61 + user's "create a todo list. spawn subagents..." + 6/6+7/7 + YML. Governance-visible hook for skills SSOT at install layer. Silent, additive, reversible, no behavior change, fw/echo only.]
|
|
9
|
+
[P3-SKILLS-FOLLOW-02: code-review package SSOT canonical src/skills/code-review/SKILL.md (next high-value per deep ref "parallel small batches" + @architect scoping rec 2 + YML @ "Ready for next" + this P3-SKILLS-FOLLOW-02 on user's spawn command); mirror .opencode/skills/code-review/ is built output of this logic; see paired guarded fw "P3-SKILLS-FOLLOW-02-code-review-ssot-preferred" in status.ts (after researcher) + rich append docs/reflections/p3-skills-follow-02-code-review-2026-05-27.md + YML @ harness-codex verification + 0 hot + 3-hot + all ties + ps 0 + this work (2-file surgical edit, harness post, mapping append after latest ~17099+, todo advance 1, spawn replacement, self-audit 100%, green + ready) + deep ref 2026-05-26 + Phase 3 Pivot + Term 61 + 6/6+7/7 + YML. Governance-visible hook for skills SSOT at install layer for code-review. Silent, additive, reversible, no behavior change, fw/echo only. "The box contains its builders. The relay is hot."] */
|
|
10
|
+
const skillsSource = fs.existsSync(path.join(packageRoot, "src", "skills"))
|
|
11
|
+
? path.join(packageRoot, "src", "skills")
|
|
12
|
+
: path.join(packageRoot, "dist", "skills");
|
|
13
|
+
const skillsDest = path.join(targetDir, ".opencode", "skills");
|
|
14
|
+
|
|
15
|
+
if (fs.existsSync(skillsSource)) {
|
|
16
|
+
try {
|
|
17
|
+
if (!fs.existsSync(skillsDest)) fs.mkdirSync(skillsDest, { recursive: true });
|
|
18
|
+
const skillDirs = fs.readdirSync(skillsSource, { withFileTypes: true });
|
|
19
|
+
let copied = 0, skipped = 0;
|
|
20
|
+
for (const entry of skillDirs) {
|
|
21
|
+
if (!entry.isDirectory()) continue;
|
|
22
|
+
const skillMd = path.join(skillsSource, entry.name, "SKILL.md");
|
|
23
|
+
if (!fs.existsSync(skillMd)) continue;
|
|
24
|
+
const destMd = path.join(skillsDest, entry.name, "SKILL.md");
|
|
25
|
+
const destDir = path.dirname(destMd);
|
|
26
|
+
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
27
|
+
if (fs.existsSync(destMd)) {
|
|
28
|
+
const destContent = fs.readFileSync(destMd, "utf8");
|
|
29
|
+
if (destContent.includes("source: community")) { skipped++; continue; }
|
|
30
|
+
if (fs.statSync(skillMd).mtime <= fs.statSync(destMd).mtime) continue;
|
|
31
|
+
}
|
|
32
|
+
fs.copyFileSync(skillMd, destMd);
|
|
33
|
+
copied++;
|
|
34
|
+
}
|
|
35
|
+
console.log(`✅ Skills: ${copied} updated, ${skipped} community skills preserved`);
|
|
36
|
+
} catch (e) { console.warn(`⚠️ Skills sync: ${e.message}`); }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 4. Create scripts symlink
|
|
40
|
+
const scriptsSource = path.join(packageRoot, "scripts");
|
|
41
|
+
const scriptsDest = path.join(targetDir, "scripts");
|
|
42
|
+
|
|
43
|
+
if (fs.existsSync(scriptsSource)) {
|
|
44
|
+
try {
|
|
45
|
+
if (fs.existsSync(scriptsDest)) {
|
|
46
|
+
const stats = fs.lstatSync(scriptsDest);
|
|
47
|
+
if (stats.isSymbolicLink()) {
|
|
48
|
+
console.log("ℹ️ Scripts symlink: exists");
|
|
49
|
+
} else {
|
|
50
|
+
console.log("⚠️ Scripts dir exists but is not a symlink");
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
fs.symlinkSync(scriptsSource, scriptsDest, "dir");
|
|
54
|
+
console.log("✅ Scripts symlink: created");
|
|
55
|
+
}
|
|
56
|
+
} catch (e) { console.warn(`⚠️ Scripts symlink: ${e.message}`); }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 5. Create dist symlink
|
|
60
|
+
const distSource = path.join(packageRoot, "dist");
|
|
61
|
+
const distDest = path.join(targetDir, "dist");
|
|
62
|
+
|
|
63
|
+
if (fs.existsSync(distSource)) {
|
|
64
|
+
try {
|
|
65
|
+
if (fs.existsSync(distDest)) {
|
|
66
|
+
const stats = fs.lstatSync(distDest);
|
|
67
|
+
if (stats.isSymbolicLink()) {
|
|
68
|
+
console.log("ℹ️ Dist symlink: exists");
|
|
69
|
+
} else {
|
|
70
|
+
console.log("⚠️ Dist exists but is not a symlink");
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
fs.symlinkSync(distSource, distDest, "dir");
|
|
74
|
+
console.log("✅ Dist symlink: created");
|
|
75
|
+
}
|
|
76
|
+
} catch (e) { console.warn(`⚠️ Dist symlink: ${e.message}`); }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = { syncSetupSkillsAndRootLinks };
|
|
82
|
+
|
|
83
|
+
if (require.main === module) {
|
|
6
84
|
const packageRoot = path.join(__dirname, "..", "..");
|
|
7
85
|
const homeDir = require("os").homedir();
|
|
8
86
|
|
|
@@ -43,37 +121,7 @@ if (hasHermes) {
|
|
|
43
121
|
* Extended header for next high-value package (code-review). src/skills/code-review/SKILL.md canonical SSOT; .opencode/skills/code-review/ built mirror of this sync logic. See paired guarded fw log "P3-SKILLS-FOLLOW-02-code-review-ssot-preferred" in status.ts getSkillsList (inserted after researcher block) + rich append docs/reflections/p3-skills-follow-02-code-review-2026-05-27.md (per AGENTS) + CGT/Governance-visible for YML @ harness-codex verification + 0 hot + 3-hot re-establish + all ties to spawn command + deep ref + pivot + Term 61 + 6/6+7/7 + YML + ps 0 + this P3-SKILLS-FOLLOW-02 full work (2-file surgical, harness post green tsc 0 new on touched, mapping append after latest, todo advance exactly 1, spawn replacement to maintain 3-hot, self-audit 100%) + verification + "the box contains its builders. The relay is hot.". 2 files max total for this follow-02. Highly modular (100% prior P3-SKILLS/YML/7th pattern reuse exactly inside existing sync logic). Fully reversible (targeted delete of notes restores exact prior). fw/echo discipline. AGENTS org (scripts/ for sh/cjs). Term 61 surgical forward motion held (no bloat, pure on actual dedup). "the box contains its builders". Green + ready. Subagent ID for resume.
|
|
44
122
|
*/
|
|
45
123
|
|
|
46
|
-
|
|
47
|
-
[P3-SKILLS-DE-DUP-RESEARCHER-FOLLOW-01: researcher package SSOT canonical src/skills/researcher/SKILL.md (high-value per deep ref + YML precedent + playbook P3-SKILLS-FOLLOW-01); mirror .opencode/skills/researcher/ is built output of this logic; see paired guarded fw in status.ts + rich append + YML @ harness-codex verification (FORCE exercised P3-YML + codex-enforcement + 100/60/0 + 3 subagents tracked + 0 hot + 3-hot re-establish + all prior green) + deep ref 2026-05-26 + Phase 3 Pivot + Term 61 + user's "create a todo list. spawn subagents..." + 6/6+7/7 + YML. Governance-visible hook for skills SSOT at install layer. Silent, additive, reversible, no behavior change, fw/echo only.]
|
|
48
|
-
[P3-SKILLS-FOLLOW-02: code-review package SSOT canonical src/skills/code-review/SKILL.md (next high-value per deep ref "parallel small batches" + @architect scoping rec 2 + YML @ "Ready for next" + this P3-SKILLS-FOLLOW-02 on user's spawn command); mirror .opencode/skills/code-review/ is built output of this logic; see paired guarded fw "P3-SKILLS-FOLLOW-02-code-review-ssot-preferred" in status.ts (after researcher) + rich append docs/reflections/p3-skills-follow-02-code-review-2026-05-27.md + YML @ harness-codex verification + 0 hot + 3-hot + all ties + ps 0 + this work (2-file surgical edit, harness post, mapping append after latest ~17099+, todo advance 1, spawn replacement, self-audit 100%, green + ready) + deep ref 2026-05-26 + Phase 3 Pivot + Term 61 + 6/6+7/7 + YML. Governance-visible hook for skills SSOT at install layer for code-review. Silent, additive, reversible, no behavior change, fw/echo only. "The box contains its builders. The relay is hot."] */
|
|
49
|
-
const skillsSource = fs.existsSync(path.join(packageRoot, "src", "skills"))
|
|
50
|
-
? path.join(packageRoot, "src", "skills")
|
|
51
|
-
: path.join(packageRoot, "dist", "skills");
|
|
52
|
-
const skillsDest = path.join(targetDir, ".opencode", "skills");
|
|
53
|
-
|
|
54
|
-
if (fs.existsSync(skillsSource)) {
|
|
55
|
-
try {
|
|
56
|
-
if (!fs.existsSync(skillsDest)) fs.mkdirSync(skillsDest, { recursive: true });
|
|
57
|
-
const skillDirs = fs.readdirSync(skillsSource, { withFileTypes: true });
|
|
58
|
-
let copied = 0, skipped = 0;
|
|
59
|
-
for (const entry of skillDirs) {
|
|
60
|
-
if (!entry.isDirectory()) continue;
|
|
61
|
-
const skillMd = path.join(skillsSource, entry.name, "SKILL.md");
|
|
62
|
-
if (!fs.existsSync(skillMd)) continue;
|
|
63
|
-
const destMd = path.join(skillsDest, entry.name, "SKILL.md");
|
|
64
|
-
const destDir = path.dirname(destMd);
|
|
65
|
-
if (!fs.existsSync(destDir)) fs.mkdirSync(destDir, { recursive: true });
|
|
66
|
-
if (fs.existsSync(destMd)) {
|
|
67
|
-
const destContent = fs.readFileSync(destMd, "utf8");
|
|
68
|
-
if (destContent.includes("source: community")) { skipped++; continue; }
|
|
69
|
-
if (fs.statSync(skillMd).mtime <= fs.statSync(destMd).mtime) continue;
|
|
70
|
-
}
|
|
71
|
-
fs.copyFileSync(skillMd, destMd);
|
|
72
|
-
copied++;
|
|
73
|
-
}
|
|
74
|
-
console.log(`✅ Skills: ${copied} updated, ${skipped} community skills preserved`);
|
|
75
|
-
} catch (e) { console.warn(`⚠️ Skills sync: ${e.message}`); }
|
|
76
|
-
}
|
|
124
|
+
syncSetupSkillsAndRootLinks(packageRoot, targetDir);
|
|
77
125
|
|
|
78
126
|
// 2. Handle opencode.json merge
|
|
79
127
|
const rootOpencodeJson = path.join(packageRoot, "opencode.json");
|
|
@@ -121,46 +169,6 @@ if (fs.existsSync(pluginSource)) {
|
|
|
121
169
|
console.log("ℹ️ Plugin source not found (build may be needed)");
|
|
122
170
|
}
|
|
123
171
|
|
|
124
|
-
// 4. Create scripts symlink
|
|
125
|
-
const scriptsSource = path.join(packageRoot, "scripts");
|
|
126
|
-
const scriptsDest = path.join(targetDir, "scripts");
|
|
127
|
-
|
|
128
|
-
if (fs.existsSync(scriptsSource)) {
|
|
129
|
-
try {
|
|
130
|
-
if (fs.existsSync(scriptsDest)) {
|
|
131
|
-
const stats = fs.lstatSync(scriptsDest);
|
|
132
|
-
if (stats.isSymbolicLink()) {
|
|
133
|
-
console.log("ℹ️ Scripts symlink: exists");
|
|
134
|
-
} else {
|
|
135
|
-
console.log("⚠️ Scripts dir exists but is not a symlink");
|
|
136
|
-
}
|
|
137
|
-
} else {
|
|
138
|
-
fs.symlinkSync(scriptsSource, scriptsDest, "dir");
|
|
139
|
-
console.log("✅ Scripts symlink: created");
|
|
140
|
-
}
|
|
141
|
-
} catch (e) { console.warn(`⚠️ Scripts symlink: ${e.message}`); }
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// 5. Create dist symlink
|
|
145
|
-
const distSource = path.join(packageRoot, "dist");
|
|
146
|
-
const distDest = path.join(targetDir, "dist");
|
|
147
|
-
|
|
148
|
-
if (fs.existsSync(distSource)) {
|
|
149
|
-
try {
|
|
150
|
-
if (fs.existsSync(distDest)) {
|
|
151
|
-
const stats = fs.lstatSync(distDest);
|
|
152
|
-
if (stats.isSymbolicLink()) {
|
|
153
|
-
console.log("ℹ️ Dist symlink: exists");
|
|
154
|
-
} else {
|
|
155
|
-
console.log("⚠️ Dist exists but is not a symlink");
|
|
156
|
-
}
|
|
157
|
-
} else {
|
|
158
|
-
fs.symlinkSync(distSource, distDest, "dir");
|
|
159
|
-
console.log("✅ Dist symlink: created");
|
|
160
|
-
}
|
|
161
|
-
} catch (e) { console.warn(`⚠️ Dist symlink: ${e.message}`); }
|
|
162
|
-
}
|
|
163
|
-
|
|
164
172
|
// 6. Convert MCP paths in consumer opencode.json
|
|
165
173
|
const isConsumer = isConsumerInstall(packageRoot, targetDir);
|
|
166
174
|
const consumerPkgName = isConsumer
|
|
@@ -234,3 +242,4 @@ if (resolvedPackage !== resolvedTarget) {
|
|
|
234
242
|
}
|
|
235
243
|
|
|
236
244
|
console.log("\n✅ xray setup complete.\n");
|
|
245
|
+
}
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
fromMemoryCapabilityMap,
|
|
15
15
|
} from './memory-routing-bridge.js';
|
|
16
16
|
import { routeSubagent } from '../../../nucleus/autonomy-kernel.js';
|
|
17
|
+
import { scoreAndRoute } from '../../../nucleus/thin-dispatch.js';
|
|
17
18
|
|
|
18
19
|
/** routeSubagent names → AGENT_REGISTRY keys */
|
|
19
20
|
const ROUTE_AGENT_ALIASES: Record<string, string> = {
|
|
@@ -102,6 +103,13 @@ export class AgentCapabilitiesManager {
|
|
|
102
103
|
operationDescription = '',
|
|
103
104
|
taskType = '',
|
|
104
105
|
): string | null {
|
|
106
|
+
if (operationDescription.trim()) {
|
|
107
|
+
const routed = scoreAndRoute(operationDescription, {});
|
|
108
|
+
if (routed.memoryRouting?.overridden && this.capabilities.has(routed.agent)) {
|
|
109
|
+
return routed.agent;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
105
113
|
if (taskType.trim()) {
|
|
106
114
|
const routed = routeSubagent(taskType);
|
|
107
115
|
const resolved = resolveRoutedAgent(routed, this.capabilities);
|
|
@@ -53,6 +53,18 @@ When `multi_agent_orchestration.lead_dev_mode` is true in `features.json` (defau
|
|
|
53
53
|
| Test failures | bug-triage |
|
|
54
54
|
| Review | code-review |
|
|
55
55
|
|
|
56
|
+
## Goggles
|
|
57
|
+
|
|
58
|
+
Pushed on `feat/goggles-look`. Not merged. Not published. Grok CLI has not shipped this. Wear the local build. From the worn checkout run `node dist/integrations/hooks/goggles-pipeline.mjs`. Do not run `npx 0xray goggles`. If `dist` is older than `src/integrations/hooks/goggles-pipeline.mjs`, build that tree and wear that `dist`. A subagent wears this same local build.
|
|
59
|
+
|
|
60
|
+
Kind 0 is actuality. It compares the list in the file to the same six names in the code. It speaks only when those lists differ. A match is quiet. It does not read the suit that is running. It is not a plate type.
|
|
61
|
+
|
|
62
|
+
Kind 1 names one plane: dichotomy, syncopate, synthesis, or loop. The lens holds that plane. An action on that plane is quiet. An action on another plane, or on a pipeline drawing, is stopped. A pipeline drawing is not a scope stop. Ground is not a scope stop. Scope, when named, is ecosystem, part, one flow, or one artifact, and an action wider than that scope is stopped. One kind and one scope level at a time. Two planes, calling, ground, and a pipeline name do not arm the lens. `outer` without one plane is `Name one plane.` After 1 is empty. Nothing is picked. Calling stays off.
|
|
63
|
+
|
|
64
|
+
`digest` and `triage` return the card already built by `assemblePlane`. The fields are from, digest, plate, entry, exit, files, skills, setup, teardown, and worn. Empty stays empty. The rows are ground, routing, house, boot, governance, memory-recall, orchestration, processor, and reporting. Those nine are not Kind 0. `digest` fills the card. Entry and exit are the plate's input and output box titles when that plate has them. Setup and teardown stay empty unless the row names them. The mill path is `scripts/foundry`. `triage` adds the empty fields and whether the row holds. Zoom after the card is the same ladder: ecosystem, part, one flow, one artifact. One file is one artifact. Several files are not narrowed to a guessed file.
|
|
65
|
+
|
|
66
|
+
The hold lasts for the work that named the plane. It does not stop one tool and then forget. Work that says goggles clears the hold and stays quiet. The suit does not invent the plane.
|
|
67
|
+
|
|
56
68
|
## Hooks (rewired, not new MCPs)
|
|
57
69
|
|
|
58
70
|
- **SessionStart** → `session-start.js` boots lead_dev_mode
|
|
@@ -421,6 +421,10 @@ export function reloadOpProc(cwd = process.cwd()) {
|
|
|
421
421
|
}
|
|
422
422
|
function mergeProjectOverlays(destPath) {
|
|
423
423
|
mergeStackOverlay(destPath);
|
|
424
|
+
// Suit heat keeps repo-* off the project file. A wake that merges them
|
|
425
|
+
// and then prunes them records a fake 59 → 45 drop on every compact.
|
|
426
|
+
if (process.env.REPERTOIRE_SUBJECT_OVERLAY === '0')
|
|
427
|
+
return;
|
|
424
428
|
mergeSubjectOverlay(destPath);
|
|
425
429
|
}
|
|
426
430
|
export function hydrateWritableSignals(seedPath, cwd = process.cwd()) {
|