oh-my-copilot 5.6.1 → 5.6.2

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/docs/CLAUDE.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <!-- OMC:START -->
2
- <!-- OMC:VERSION:5.6.1 -->
2
+ <!-- OMC:VERSION:5.6.2 -->
3
3
 
4
4
  # oh-my-copilot - Intelligent Multi-Agent Orchestration
5
5
 
package/docs/MIGRATION.md CHANGED
@@ -8,6 +8,7 @@ This guide covers all migration paths for oh-my-copilot. Find your current versi
8
8
 
9
9
  - [Unreleased: Team Instance Ownership](#unreleased-team-instance-ownership)
10
10
  - [Unreleased: Cancellation Scope](#unreleased-cancellation-scope)
11
+ - [v5.6.1 → v5.6.2: Postinstall Hook](#v561--v562-postinstall-hook)
11
12
  - [v5.5.0 → v5.6.1: Fork Upgrade Guide](#v550--v561-fork-upgrade-guide)
12
13
  - [v5.1.0 → v5.5.0: Fork Upgrade Guide](#v510--v550-fork-upgrade-guide)
13
14
  - [v4.13.102 → v5.0.0: Fork Upgrade Guide](#v413102--v500-fork-upgrade-guide)
@@ -121,6 +122,22 @@ locations and descendants of system temp/OS roots are never used as roots.
121
122
 
122
123
  ---
123
124
 
125
+ ## v5.6.1 → v5.6.2: Postinstall Hook
126
+
127
+ Fork **v5.6.2** ports upstream oh-my-claudecode `dev` 4280efb1f..486b85bbb.
128
+ There is nothing to migrate: no config, command or skill changes.
129
+
130
+ - Update with `npm install -g oh-my-copilot@5.6.2` or
131
+ `copilot plugin update oh-my-copilot@omc`.
132
+ - `npm install` now runs `scripts/postinstall-contained-fs.mjs`. On macOS it
133
+ builds the contained-fs native addon if it is missing; if Node headers or
134
+ Xcode Command Line Tools are unavailable it prints a warning and you can
135
+ build later with `node scripts/build-contained-fs.mjs` from the package
136
+ root. On Linux and Windows it does nothing. The hook always exits 0, so it
137
+ never fails the install.
138
+
139
+ ---
140
+
124
141
  ## v5.5.0 → v5.6.1: Fork Upgrade Guide
125
142
 
126
143
  This section covers the upgrade from fork **v5.5.0** to fork **v5.6.1**. The
package/docs/REFERENCE.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Complete reference for oh-my-copilot. For quick start, see the main [README.md](../README.md).
4
4
 
5
- For v5.6.1, the plugin ships 20 agents, 61 skills, 21 command files, and one configured MCP server exposing exactly 55 tools.
5
+ For v5.6.2, the plugin ships 20 agents, 61 skills, 21 command files, and one configured MCP server exposing exactly 55 tools.
6
6
 
7
7
  ---
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-copilot",
3
- "version": "5.6.1",
3
+ "version": "5.6.2",
4
4
  "description": "Multi-agent orchestration system for Copilot CLI - Inspired by oh-my-opencode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -34,6 +34,9 @@
34
34
  "bridge/runtime-cli.cjs",
35
35
  "commands",
36
36
  "hooks",
37
+ "scripts/build-contained-fs.mjs",
38
+ "scripts/postinstall-contained-fs.mjs",
39
+ "scripts/verify-graph-contained-fs.mjs",
37
40
  "scripts",
38
41
  "skills",
39
42
  "templates",
@@ -92,6 +95,7 @@
92
95
  "generate:prompt-projections": "node scripts/generate-prompt-projections.mjs",
93
96
  "verify:prompt-projections": "node scripts/generate-prompt-projections.mjs --verify",
94
97
  "build:contained-fs": "node scripts/build-contained-fs.mjs",
98
+ "postinstall": "node scripts/postinstall-contained-fs.mjs",
95
99
  "build:copilot-hooks": "node scripts/copilot/build-hooks.mjs --write",
96
100
  "verify:copilot-hooks": "node scripts/copilot/build-hooks.mjs --verify",
97
101
  "build:copilot-agents": "node scripts/copilot/build-agents.mjs --write",
@@ -155,5 +159,5 @@
155
159
  "publishConfig": {
156
160
  "access": "public"
157
161
  },
158
- "gitHead": "ce5f338d6bc2e4dff0e6af4c15f0c1bb09d93c54"
162
+ "gitHead": "dff284086ef69f7bd488ba13346e66a90180d671"
159
163
  }
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-copilot",
3
- "version": "5.6.1",
3
+ "version": "5.6.2",
4
4
  "description": "Multi-agent orchestration system for GitHub Copilot CLI",
5
5
  "author": {
6
6
  "name": "oh-my-copilot contributors"
@@ -6,8 +6,24 @@ import { spawnSync } from 'node:child_process';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  // Build-time only. Runtime never invokes a compiler or downloads a binary.
9
- if (process.platform !== 'darwin' && !process.argv.includes('--force')) process.exit(0);
10
- if (!['darwin', 'linux'].includes(process.platform)) throw new Error('Unsupported native build platform');
9
+
10
+ // Original behavior: darwin only, unless --optional or --force is passed
11
+ const isOptional = process.argv.includes('--optional');
12
+ const isForceBuild = process.argv.includes('--force');
13
+
14
+ // Skip on non-darwin platforms unless explicitly forced or optional
15
+ if (process.platform !== 'darwin' && !isForceBuild && !isOptional) {
16
+ process.exit(0);
17
+ }
18
+
19
+ // Fail loudly if platform is unsupported AND not optional
20
+ if (!['darwin', 'linux'].includes(process.platform)) {
21
+ if (isOptional) {
22
+ process.exit(0);
23
+ }
24
+ throw new Error('Unsupported native build platform');
25
+ }
26
+
11
27
  const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
12
28
  const explicit = process.argv.find(arg => arg.startsWith('--headers='))?.slice('--headers='.length);
13
29
  const version = process.versions.node;
@@ -20,10 +36,16 @@ const candidates = [
20
36
  '/usr/local/include/node',
21
37
  '/usr/include/node',
22
38
  ].filter(Boolean);
39
+
23
40
  const headers = candidates.find(path => existsSync(join(path, 'node_api.h')));
24
41
  if (!headers) {
42
+ if (isOptional) {
43
+ // Graceful skip for optional builds
44
+ process.exit(0);
45
+ }
25
46
  throw new Error('Node development headers are required. Supply --headers=/absolute/path/to/include/node (node_api.h), or populate the node-gyp cache before building. No headers are downloaded by this script.');
26
47
  }
48
+
27
49
  for (const arch of process.platform === 'darwin' ? ['arm64', 'x64'] : [process.arch]) {
28
50
  const output = join(root, 'native', `contained-fs-${process.platform}-${arch}.node`);
29
51
  mkdirSync(dirname(output), { recursive: true });
@@ -554,6 +554,14 @@ async function main() {
554
554
  process.exit(0);
555
555
  }
556
556
 
557
+ // Blocking requires both a destructive command and an active guard. The
558
+ // command parse is pure and cheap; the mode lookup reads state and runs git,
559
+ // so only pay for it when the command could actually be blocked (#4221).
560
+ const command = commandFromPayload(payload);
561
+ if (!command) process.exit(0);
562
+ const label = destructiveCommandLabel(command);
563
+ if (!label) process.exit(0);
564
+
557
565
  const explicit = process.env.OMC_GIT_GUARDRAILS === '1';
558
566
  let activeMode = null;
559
567
  if (!explicit) {
@@ -566,15 +574,8 @@ async function main() {
566
574
  if (!activeMode) process.exit(0);
567
575
  }
568
576
 
569
- const command = commandFromPayload(payload);
570
- if (!command) process.exit(0);
571
-
572
- const label = destructiveCommandLabel(command);
573
- if (label) {
574
- process.stderr.write(`${guardMessage(label, activeMode)}\n`);
575
- process.exit(2);
576
- }
577
- process.exit(0);
577
+ process.stderr.write(`${guardMessage(label, activeMode)}\n`);
578
+ process.exit(2);
578
579
  }
579
580
 
580
581
  await main();
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Optional postinstall hook for contained-fs native module.
4
+ *
5
+ * Follows the same platform constraints as build-contained-fs.mjs:
6
+ * - darwin: always attempt to build
7
+ * - linux: skip gracefully (not built by default)
8
+ * - other: skip gracefully
9
+ *
10
+ * Also skips in development environments (when .git exists).
11
+ */
12
+
13
+ import { existsSync } from 'node:fs';
14
+ import { resolve, dirname } from 'node:path';
15
+ import { spawnSync } from 'node:child_process';
16
+ import { fileURLToPath } from 'node:url';
17
+
18
+ // Determine package root
19
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
20
+ const packageRoot = resolve(scriptDir, '..');
21
+
22
+ // Skip if we're in development (source repo has .git)
23
+ if (existsSync(resolve(packageRoot, '.git'))) {
24
+ process.exit(0);
25
+ }
26
+
27
+ // Skip on non-darwin platforms (consistent with build script default)
28
+ if (process.platform !== 'darwin') {
29
+ process.exit(0);
30
+ }
31
+
32
+ // Check if native binary already exists for darwin
33
+ const nativePath = `contained-fs-${process.platform}-${process.arch}.node`;
34
+ const nativeBinary = resolve(packageRoot, 'native', nativePath);
35
+ if (existsSync(nativeBinary)) {
36
+ process.exit(0);
37
+ }
38
+
39
+ // Attempt to build the optional native module on darwin. A failed build must
40
+ // not fail `npm install`, but it must tell the user how to recover.
41
+ const buildScript = resolve(scriptDir, 'build-contained-fs.mjs');
42
+ const result = spawnSync(process.execPath, [buildScript, '--optional'], {
43
+ stdio: ['ignore', 'ignore', 'pipe'],
44
+ timeout: 120000,
45
+ });
46
+
47
+ if (!existsSync(nativeBinary)) {
48
+ const detail = result.error?.message ?? result.stderr?.toString().trim().split('\n').pop() ?? '';
49
+ console.warn(
50
+ `[oh-my-copilot] contained-fs native addon was not built${detail ? ` (${detail})` : ''}. ` +
51
+ `omg team/graph commands need it: run \`node scripts/build-contained-fs.mjs\` from ${packageRoot} ` +
52
+ '(requires Xcode Command Line Tools and Node headers).',
53
+ );
54
+ }
55
+
56
+ process.exit(0);
package/scripts/run.cjs CHANGED
@@ -166,6 +166,7 @@ function resolveInnerTimeoutMs(manifestHook, platform = process.platform) {
166
166
  const TRUSTED_WORKER_HOOKS = new Map([
167
167
  ['keyword-detector.mjs', { event: 'UserPromptSubmit', timeoutCapMs: 8000 }],
168
168
  ['skill-injector.mjs', { event: 'UserPromptSubmit', timeoutCapMs: 12000 }],
169
+ ['git-guardrails.mjs', { event: 'PreToolUse' }],
169
170
  ['pre-tool-enforcer.mjs', { event: 'PreToolUse' }],
170
171
  ['post-tool-verifier.mjs', { event: 'PostToolUse' }],
171
172
  ['project-memory-posttool.mjs', { event: 'PostToolUse' }],
@@ -930,6 +931,15 @@ import(targetUrl).then(
930
931
  );
931
932
  `;
932
933
 
934
+ /**
935
+ * git-guardrails.mjs is a no-op when explicitly disabled; skip starting its
936
+ * worker entirely. Returns 0 to exit, or null to run the worker.
937
+ */
938
+ function gitGuardrailsPreCheck() {
939
+ if (process.env.OMC_GIT_GUARDRAILS === '0') return 0;
940
+ return null;
941
+ }
942
+
933
943
  async function runWorker(targetPath, manifestHook, timeoutMs) {
934
944
  let worker;
935
945
  let terminal = false;
@@ -1034,6 +1044,14 @@ if (require.main === module) {
1034
1044
  const extraArgs = process.argv.slice(3);
1035
1045
  const workerManifestHook = resolveWorkerTarget(resolution, extraArgs);
1036
1046
  if (workerManifestHook) {
1047
+ // Pre-check for git-guardrails: exit immediately if guard is disabled
1048
+ if (basename(resolution.targetPath) === 'git-guardrails.mjs') {
1049
+ const preCheckResult = gitGuardrailsPreCheck();
1050
+ if (preCheckResult === 0) {
1051
+ process.exitCode = 0;
1052
+ return;
1053
+ }
1054
+ }
1037
1055
  const workerTimeoutMs = resolveTrustedWorkerTimeoutMs(resolution.targetPath, workerManifestHook);
1038
1056
  runWorker(resolution.targetPath, workerManifestHook, workerTimeoutMs).then(status => {
1039
1057
  process.exitCode = status;