0xray 4.0.28 → 4.0.29

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.
@@ -2,12 +2,8 @@
2
2
 
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
- const {
6
- installAllBridges,
7
- resolveConsumerTargetDir,
8
- isConsumerInstall,
9
- } = require("./install-bridges.cjs");
10
- const { applyConsumerGitignore } = require("./consumer-gitignore.cjs");
5
+ const { resolveConsumerTargetDir } = require("./install-bridges.cjs");
6
+ const { linkVendoredRepertoire } = require("./wear-vendored-repertoire.cjs");
11
7
  const {
12
8
  overlayConsumerTree,
13
9
  mintConsumerFromSsot,
@@ -18,12 +14,6 @@ const {
18
14
  readPackageIdentity,
19
15
  } = require("../foundry/mint-suit.cjs");
20
16
 
21
- function structuredLog(component, action, status, details) {
22
- const ts = new Date().toISOString();
23
- const detailsPart = details ? ` | ${JSON.stringify(details)}` : "";
24
- console.log(`${ts} [${component}] ${action} - ${String(status).toUpperCase()}${detailsPart}`);
25
- }
26
-
27
17
  const XRAY_MANAGED_AGENTS_MARKER = "<!-- 0xray-managed -->";
28
18
  const XRAY_MANAGED_AGENTS_BEGIN = "<!-- 0xray-managed:begin -->";
29
19
  const XRAY_MANAGED_AGENTS_END = "<!-- 0xray-managed:end -->";
@@ -85,53 +75,10 @@ function deployManagedAgents(packageRoot, targetDir, log) {
85
75
  if (updated !== current) fs.writeFileSync(agentsDest, updated);
86
76
  }
87
77
 
88
- function deployConsumerGitignore(packageRoot, targetDir, log) {
89
- const gitignoreResult = applyConsumerGitignore(targetDir, packageRoot);
90
- if (gitignoreResult === "created") {
91
- log("postinstall", "Created .gitignore from template", "info");
92
- } else if (gitignoreResult === "merged") {
93
- log("postinstall", "Merged 0xray suit entries into .gitignore", "info");
94
- }
95
- }
96
-
97
- /**
98
- * Wear bridges for consumers (full 4-platform) and the framework repo (dogfood).
99
- * installAllBridges already decides which path.
100
- */
101
- function runPostinstall(packageRoot, targetDir, log) {
102
- const logFn = log || structuredLog;
103
- const resolvedPackage = path.resolve(packageRoot);
104
- const resolvedTarget = path.resolve(targetDir);
105
- const consumer = isConsumerInstall(resolvedPackage, resolvedTarget);
106
-
107
- if (consumer) {
108
- deployManagedAgents(resolvedPackage, resolvedTarget, logFn);
109
- deployConsumerGitignore(resolvedPackage, resolvedTarget, logFn);
110
- }
111
-
112
- try {
113
- installAllBridges({
114
- targetDir: resolvedTarget,
115
- packageRoot: resolvedPackage,
116
- log: logFn,
117
- });
118
- if (consumer) {
119
- mintConsumerSuit(resolvedPackage, resolvedTarget, logFn);
120
- }
121
- } catch (e) {
122
- logFn("postinstall", "Bridge install failed", "error", { error: e.message });
123
- throw e;
124
- }
125
-
126
- if (consumer) {
127
- logFn(
128
- "postinstall",
129
- "0xRay framework installed (4 bridges). Run `npx 0xray setup` for symlinks/Hermes skill extras.",
130
- "success",
131
- );
132
- } else {
133
- logFn("postinstall", "framework dogfood wear complete", "success");
134
- }
78
+ /** npm install links vendored @0xray/repertoire and nothing else. The suit is `npx 0xray wear`. */
79
+ function runPostinstall(packageRoot, targetDir, _log) {
80
+ linkVendoredRepertoire(packageRoot, targetDir);
81
+ console.log("Run `npx 0xray wear`");
135
82
  }
136
83
 
137
84
  module.exports = {
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Remove the Cursor suit. Prints "restored" only when the file bytes match
4
+ * the snapshot exactly. A mismatch keeps the snapshot and exits non-zero.
5
+ *
6
+ * npx 0xray unwear
7
+ * node node_modules/0xray/scripts/node/unwear-cursor-hooks.cjs [project]
8
+ */
9
+ const path = require("path");
10
+ const { unwearCursorHooks } = require("./install-bridges.cjs");
11
+
12
+ const target = path.resolve(process.argv[2] || process.cwd());
13
+ let restored = false;
14
+ try {
15
+ restored = unwearCursorHooks(target);
16
+ } catch (err) {
17
+ process.stderr.write(`${err && err.message ? err.message : err}\n`);
18
+ process.exit(1);
19
+ }
20
+ if (!restored) process.exit(1);
21
+ process.stdout.write(`unwear: restored cursor hooks at ${target}\n`);
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Wear the Cursor suit in a git work tree.
4
+ * npx 0xray wear
5
+ * node node_modules/0xray/scripts/node/wear-cursor-hooks.cjs [project]
6
+ */
7
+ const path = require("path");
8
+ const { wearCursorHooks } = require("./install-bridges.cjs");
9
+
10
+ const target = path.resolve(process.argv[2] || process.cwd());
11
+ const packageRoot = path.resolve(__dirname, "..", "..");
12
+ try {
13
+ wearCursorHooks(target, packageRoot, () => {});
14
+ } catch (err) {
15
+ process.stderr.write(`${err && err.message ? err.message : err}\n`);
16
+ process.exit(1);
17
+ }
@@ -122,6 +122,38 @@ function wearDestinations(packageRoot, targetDir) {
122
122
  return dests;
123
123
  }
124
124
 
125
+ function repertoireLinkDest(targetDir) {
126
+ return path.join(targetDir, "node_modules", "@0xray", "repertoire");
127
+ }
128
+
129
+ function relativeRepertoireLink(vendor, dest) {
130
+ return path.relative(path.dirname(dest), vendor);
131
+ }
132
+
133
+ /**
134
+ * Create one relative symlink at <target>/node_modules/@0xray/repertoire.
135
+ * A real directory or a symlink that is not this link is left in place.
136
+ */
137
+ function linkVendoredRepertoire(packageRoot, targetDir) {
138
+ const vendor = resolveVendoredRepertoire(packageRoot);
139
+ if (!vendor) return { linked: false, vendor: null, dest: null };
140
+ const dest = repertoireLinkDest(targetDir);
141
+ const rel = relativeRepertoireLink(vendor, dest);
142
+ try {
143
+ const st = fs.lstatSync(dest);
144
+ if (st.isSymbolicLink() && fs.readlinkSync(dest) === rel) {
145
+ return { linked: true, vendor, dest, unchanged: true };
146
+ }
147
+ return { linked: false, vendor, dest, skipped: true };
148
+ } catch {
149
+ /* dest absent */
150
+ }
151
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
152
+ const linkType = process.platform === "win32" ? "junction" : "dir";
153
+ fs.symlinkSync(rel, dest, linkType);
154
+ return { linked: true, vendor, dest, unchanged: false };
155
+ }
156
+
125
157
  function wearVendoredRepertoire(packageRoot, targetDir, log) {
126
158
  const vendor = resolveVendoredRepertoire(packageRoot);
127
159
  if (!vendor) return { worn: [], vendor: null };
@@ -153,6 +185,9 @@ function hasFileProtocolDependency(pkg) {
153
185
  module.exports = {
154
186
  resolveVendoredRepertoire,
155
187
  wearVendoredRepertoire,
188
+ linkVendoredRepertoire,
189
+ relativeRepertoireLink,
190
+ repertoireLinkDest,
156
191
  wearDestinations,
157
192
  hasFileProtocolDependency,
158
193
  };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xray-pre-tool",
3
- "version": "4.0.28",
3
+ "version": "4.0.29",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "0xRay constitution + temperament PreToolUse for OpenClaw",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./features.schema.json",
3
- "version": "4.0.28",
3
+ "version": "4.0.29",
4
4
  "description": "0xRay Framework - Unified Feature Configuration",
5
5
  "suit_temperament": {
6
6
  "profile": "auto",