@su-record/vibe 2.11.0 → 2.12.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.
Files changed (250) hide show
  1. package/README.en.md +23 -28
  2. package/README.md +10 -9
  3. package/dist/cli/auth.d.ts +2 -2
  4. package/dist/cli/auth.js +12 -12
  5. package/dist/cli/auth.js.map +1 -1
  6. package/dist/cli/commands/codex-proxy.d.ts +1 -1
  7. package/dist/cli/commands/codex-proxy.js +11 -11
  8. package/dist/cli/commands/codex-proxy.js.map +1 -1
  9. package/dist/cli/commands/config.d.ts +1 -1
  10. package/dist/cli/commands/config.d.ts.map +1 -1
  11. package/dist/cli/commands/config.js +22 -21
  12. package/dist/cli/commands/config.js.map +1 -1
  13. package/dist/cli/commands/info.js +2 -2
  14. package/dist/cli/commands/init.d.ts +2 -2
  15. package/dist/cli/commands/init.d.ts.map +1 -1
  16. package/dist/cli/commands/init.js +20 -16
  17. package/dist/cli/commands/init.js.map +1 -1
  18. package/dist/cli/commands/setup.d.ts +1 -1
  19. package/dist/cli/commands/setup.js +24 -24
  20. package/dist/cli/commands/setup.js.map +1 -1
  21. package/dist/cli/commands/skills.d.ts.map +1 -1
  22. package/dist/cli/commands/skills.js +8 -7
  23. package/dist/cli/commands/skills.js.map +1 -1
  24. package/dist/cli/commands/update.d.ts.map +1 -1
  25. package/dist/cli/commands/update.js +28 -16
  26. package/dist/cli/commands/update.js.map +1 -1
  27. package/dist/cli/index.js +22 -23
  28. package/dist/cli/index.js.map +1 -1
  29. package/dist/cli/llm/antigravity-commands.d.ts +25 -0
  30. package/dist/cli/llm/antigravity-commands.d.ts.map +1 -0
  31. package/dist/cli/llm/antigravity-commands.js +142 -0
  32. package/dist/cli/llm/antigravity-commands.js.map +1 -0
  33. package/dist/cli/llm/claude-commands.d.ts.map +1 -1
  34. package/dist/cli/llm/claude-commands.js +3 -1
  35. package/dist/cli/llm/claude-commands.js.map +1 -1
  36. package/dist/cli/llm/config.js +7 -7
  37. package/dist/cli/llm/config.js.map +1 -1
  38. package/dist/cli/llm/gemini-commands.d.ts.map +1 -1
  39. package/dist/cli/llm/gemini-commands.js +7 -4
  40. package/dist/cli/llm/gemini-commands.js.map +1 -1
  41. package/dist/cli/llm/gpt-commands.d.ts.map +1 -1
  42. package/dist/cli/llm/gpt-commands.js +3 -3
  43. package/dist/cli/llm/gpt-commands.js.map +1 -1
  44. package/dist/cli/llm/help.js +4 -4
  45. package/dist/cli/llm/index.d.ts +1 -1
  46. package/dist/cli/llm/index.d.ts.map +1 -1
  47. package/dist/cli/llm/index.js +1 -1
  48. package/dist/cli/llm/index.js.map +1 -1
  49. package/dist/cli/llm.d.ts +2 -2
  50. package/dist/cli/llm.js +2 -2
  51. package/dist/cli/postinstall/constants.js +6 -6
  52. package/dist/cli/postinstall/constants.js.map +1 -1
  53. package/dist/cli/postinstall/inline-skills.js +5 -5
  54. package/dist/cli/postinstall/inline-skills.js.map +1 -1
  55. package/dist/cli/postinstall/main.d.ts.map +1 -1
  56. package/dist/cli/postinstall/main.js +14 -9
  57. package/dist/cli/postinstall/main.js.map +1 -1
  58. package/dist/cli/setup/CodexHooks.d.ts +20 -0
  59. package/dist/cli/setup/CodexHooks.d.ts.map +1 -0
  60. package/dist/cli/setup/CodexHooks.js +50 -0
  61. package/dist/cli/setup/CodexHooks.js.map +1 -0
  62. package/dist/cli/setup/CodexHooks.test.d.ts +2 -0
  63. package/dist/cli/setup/CodexHooks.test.d.ts.map +1 -0
  64. package/dist/cli/setup/CodexHooks.test.js +23 -0
  65. package/dist/cli/setup/CodexHooks.test.js.map +1 -0
  66. package/dist/cli/setup/LegacyMigration.js +2 -2
  67. package/dist/cli/setup/ProjectSetup.d.ts +4 -4
  68. package/dist/cli/setup/ProjectSetup.d.ts.map +1 -1
  69. package/dist/cli/setup/ProjectSetup.js +21 -19
  70. package/dist/cli/setup/ProjectSetup.js.map +1 -1
  71. package/dist/cli/setup/index.d.ts +1 -0
  72. package/dist/cli/setup/index.d.ts.map +1 -1
  73. package/dist/cli/setup/index.js +1 -0
  74. package/dist/cli/setup/index.js.map +1 -1
  75. package/dist/cli/setup.d.ts +2 -1
  76. package/dist/cli/setup.d.ts.map +1 -1
  77. package/dist/cli/setup.js +2 -1
  78. package/dist/cli/setup.js.map +1 -1
  79. package/dist/cli/types.d.ts +7 -9
  80. package/dist/cli/types.d.ts.map +1 -1
  81. package/dist/cli/utils/cli-detector.d.ts +5 -5
  82. package/dist/cli/utils/cli-detector.d.ts.map +1 -1
  83. package/dist/cli/utils/cli-detector.js +18 -14
  84. package/dist/cli/utils/cli-detector.js.map +1 -1
  85. package/dist/cli/utils/cli-detector.test.d.ts +2 -0
  86. package/dist/cli/utils/cli-detector.test.d.ts.map +1 -0
  87. package/dist/cli/utils/cli-detector.test.js +51 -0
  88. package/dist/cli/utils/cli-detector.test.js.map +1 -0
  89. package/dist/infra/lib/ReviewRace.d.ts +4 -4
  90. package/dist/infra/lib/ReviewRace.d.ts.map +1 -1
  91. package/dist/infra/lib/ReviewRace.js +16 -16
  92. package/dist/infra/lib/ReviewRace.js.map +1 -1
  93. package/dist/infra/lib/SkillRepository.js +7 -7
  94. package/dist/infra/lib/antigravity/auth.d.ts +18 -0
  95. package/dist/infra/lib/antigravity/auth.d.ts.map +1 -0
  96. package/dist/infra/lib/antigravity/auth.js +32 -0
  97. package/dist/infra/lib/antigravity/auth.js.map +1 -0
  98. package/dist/infra/lib/antigravity/capabilities.d.ts +28 -0
  99. package/dist/infra/lib/antigravity/capabilities.d.ts.map +1 -0
  100. package/dist/infra/lib/antigravity/capabilities.js +178 -0
  101. package/dist/infra/lib/antigravity/capabilities.js.map +1 -0
  102. package/dist/infra/lib/antigravity/chat.d.ts +34 -0
  103. package/dist/infra/lib/antigravity/chat.d.ts.map +1 -0
  104. package/dist/infra/lib/antigravity/chat.js +160 -0
  105. package/dist/infra/lib/antigravity/chat.js.map +1 -0
  106. package/dist/infra/lib/antigravity/completion.d.ts +12 -0
  107. package/dist/infra/lib/antigravity/completion.d.ts.map +1 -0
  108. package/dist/infra/lib/antigravity/completion.js +13 -0
  109. package/dist/infra/lib/antigravity/completion.js.map +1 -0
  110. package/dist/infra/lib/antigravity/constants.d.ts +8 -0
  111. package/dist/infra/lib/antigravity/constants.d.ts.map +1 -0
  112. package/dist/infra/lib/antigravity/constants.js +11 -0
  113. package/dist/infra/lib/antigravity/constants.js.map +1 -0
  114. package/dist/infra/lib/antigravity/index.d.ts +13 -0
  115. package/dist/infra/lib/antigravity/index.d.ts.map +1 -0
  116. package/dist/infra/lib/antigravity/index.js +12 -0
  117. package/dist/infra/lib/antigravity/index.js.map +1 -0
  118. package/dist/infra/lib/antigravity/models.d.ts +11 -0
  119. package/dist/infra/lib/antigravity/models.d.ts.map +1 -0
  120. package/dist/infra/lib/antigravity/models.js +38 -0
  121. package/dist/infra/lib/antigravity/models.js.map +1 -0
  122. package/dist/infra/lib/antigravity/orchestration.d.ts +33 -0
  123. package/dist/infra/lib/antigravity/orchestration.d.ts.map +1 -0
  124. package/dist/infra/lib/antigravity/orchestration.js +62 -0
  125. package/dist/infra/lib/antigravity/orchestration.js.map +1 -0
  126. package/dist/infra/lib/antigravity/types.d.ts +115 -0
  127. package/dist/infra/lib/antigravity/types.d.ts.map +1 -0
  128. package/dist/infra/lib/antigravity/types.js +5 -0
  129. package/dist/infra/lib/antigravity/types.js.map +1 -0
  130. package/dist/infra/lib/codex-proxy.d.ts +1 -1
  131. package/dist/infra/lib/codex-proxy.js +9 -9
  132. package/dist/infra/lib/codex-proxy.js.map +1 -1
  133. package/dist/infra/lib/config/GlobalConfigManager.d.ts +6 -3
  134. package/dist/infra/lib/config/GlobalConfigManager.d.ts.map +1 -1
  135. package/dist/infra/lib/config/GlobalConfigManager.js +47 -37
  136. package/dist/infra/lib/config/GlobalConfigManager.js.map +1 -1
  137. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts +2 -0
  138. package/dist/infra/lib/config/GlobalConfigManager.test.d.ts.map +1 -0
  139. package/dist/infra/lib/config/GlobalConfigManager.test.js +9 -0
  140. package/dist/infra/lib/config/GlobalConfigManager.test.js.map +1 -0
  141. package/dist/infra/lib/constants.js +1 -1
  142. package/dist/infra/lib/constants.js.map +1 -1
  143. package/dist/infra/lib/gemini/auth.d.ts +3 -3
  144. package/dist/infra/lib/gemini/auth.js +9 -9
  145. package/dist/infra/lib/gemini/auth.js.map +1 -1
  146. package/dist/infra/lib/llm/auth/AuthProfileManager.d.ts +3 -3
  147. package/dist/infra/lib/llm/auth/AuthProfileManager.d.ts.map +1 -1
  148. package/dist/infra/lib/llm/auth/AuthProfileManager.js.map +1 -1
  149. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js +8 -8
  150. package/dist/infra/lib/llm/auth/AuthProfileManager.test.js.map +1 -1
  151. package/dist/infra/lib/llm/auth/ConfigManager.js +2 -2
  152. package/dist/infra/lib/llm/auth/ConfigManager.js.map +1 -1
  153. package/dist/infra/lib/llm/auth/TokenRefresher.d.ts +1 -1
  154. package/dist/infra/lib/llm/auth/TokenRefresher.js +1 -1
  155. package/dist/infra/lib/llm/auth/index.js +1 -1
  156. package/dist/infra/lib/llm/auth/index.js.map +1 -1
  157. package/dist/infra/lib/llm/index.d.ts +1 -1
  158. package/dist/infra/lib/llm/index.js +1 -1
  159. package/dist/infra/lib/llm/types.d.ts +3 -3
  160. package/dist/infra/lib/llm/types.d.ts.map +1 -1
  161. package/dist/infra/lib/llm/types.js +1 -1
  162. package/dist/infra/lib/llm/utils/stream.js +1 -1
  163. package/dist/infra/lib/llm/utils/stream.js.map +1 -1
  164. package/dist/infra/lib/llm-availability.d.ts +5 -5
  165. package/dist/infra/lib/llm-availability.d.ts.map +1 -1
  166. package/dist/infra/lib/llm-availability.js +13 -10
  167. package/dist/infra/lib/llm-availability.js.map +1 -1
  168. package/dist/infra/lib/llm-availability.test.d.ts +2 -0
  169. package/dist/infra/lib/llm-availability.test.d.ts.map +1 -0
  170. package/dist/infra/lib/llm-availability.test.js +36 -0
  171. package/dist/infra/lib/llm-availability.test.js.map +1 -0
  172. package/dist/infra/lib/ui-ux/UiUxWorkflow.d.ts.map +1 -1
  173. package/dist/infra/lib/ui-ux/UiUxWorkflow.js +23 -5
  174. package/dist/infra/lib/ui-ux/UiUxWorkflow.js.map +1 -1
  175. package/dist/infra/orchestrator/AgentExecutor.d.ts.map +1 -1
  176. package/dist/infra/orchestrator/AgentExecutor.js +30 -1
  177. package/dist/infra/orchestrator/AgentExecutor.js.map +1 -1
  178. package/dist/infra/orchestrator/AgentManifestCache.js +1 -1
  179. package/dist/infra/orchestrator/AgentManifestCache.js.map +1 -1
  180. package/dist/infra/orchestrator/BackgroundManager.js +2 -2
  181. package/dist/infra/orchestrator/BackgroundManager.js.map +1 -1
  182. package/dist/infra/orchestrator/CodexAgentRuntime.d.ts +12 -0
  183. package/dist/infra/orchestrator/CodexAgentRuntime.d.ts.map +1 -0
  184. package/dist/infra/orchestrator/CodexAgentRuntime.js +94 -0
  185. package/dist/infra/orchestrator/CodexAgentRuntime.js.map +1 -0
  186. package/dist/infra/orchestrator/CodexAgentRuntime.test.d.ts +2 -0
  187. package/dist/infra/orchestrator/CodexAgentRuntime.test.d.ts.map +1 -0
  188. package/dist/infra/orchestrator/CodexAgentRuntime.test.js +37 -0
  189. package/dist/infra/orchestrator/CodexAgentRuntime.test.js.map +1 -0
  190. package/dist/infra/orchestrator/LLMCluster.d.ts +11 -11
  191. package/dist/infra/orchestrator/LLMCluster.d.ts.map +1 -1
  192. package/dist/infra/orchestrator/LLMCluster.js +22 -22
  193. package/dist/infra/orchestrator/LLMCluster.js.map +1 -1
  194. package/dist/infra/orchestrator/MultiLlmResearch.d.ts +3 -3
  195. package/dist/infra/orchestrator/MultiLlmResearch.d.ts.map +1 -1
  196. package/dist/infra/orchestrator/MultiLlmResearch.js +17 -17
  197. package/dist/infra/orchestrator/MultiLlmResearch.js.map +1 -1
  198. package/dist/infra/orchestrator/SmartRouter.d.ts +2 -2
  199. package/dist/infra/orchestrator/SmartRouter.js +7 -7
  200. package/dist/infra/orchestrator/SmartRouter.js.map +1 -1
  201. package/dist/infra/orchestrator/SmartRouter.test.js +74 -74
  202. package/dist/infra/orchestrator/SmartRouter.test.js.map +1 -1
  203. package/dist/infra/orchestrator/agentDiscovery.d.ts +1 -1
  204. package/dist/infra/orchestrator/agentDiscovery.js +4 -4
  205. package/dist/infra/orchestrator/agentDiscovery.js.map +1 -1
  206. package/dist/infra/orchestrator/index.d.ts +17 -17
  207. package/dist/infra/orchestrator/index.d.ts.map +1 -1
  208. package/dist/infra/orchestrator/index.js +30 -30
  209. package/dist/infra/orchestrator/index.js.map +1 -1
  210. package/dist/infra/orchestrator/orchestrator.d.ts +4 -4
  211. package/dist/infra/orchestrator/orchestrator.d.ts.map +1 -1
  212. package/dist/infra/orchestrator/orchestrator.js +5 -5
  213. package/dist/infra/orchestrator/orchestrator.js.map +1 -1
  214. package/dist/infra/orchestrator/parallelResearch.d.ts.map +1 -1
  215. package/dist/infra/orchestrator/parallelResearch.js +11 -0
  216. package/dist/infra/orchestrator/parallelResearch.js.map +1 -1
  217. package/dist/infra/orchestrator/types.d.ts +7 -8
  218. package/dist/infra/orchestrator/types.d.ts.map +1 -1
  219. package/dist/infra/orchestrator/types.js +17 -18
  220. package/dist/infra/orchestrator/types.js.map +1 -1
  221. package/dist/tools/spec/specGenerator.d.ts +1 -1
  222. package/dist/tools/spec/specGenerator.js +1 -1
  223. package/hooks/antigravity-hooks.json +73 -0
  224. package/hooks/scripts/__tests__/codex-hook-adapter.test.js +31 -0
  225. package/hooks/scripts/__tests__/hook-payload.test.js +29 -0
  226. package/hooks/scripts/__tests__/llm-orchestrate-antigravity.test.js +63 -0
  227. package/hooks/scripts/codex-hook-adapter.js +124 -0
  228. package/hooks/scripts/codex-review-gate.js +7 -3
  229. package/hooks/scripts/devlog-gen.js +1 -1
  230. package/hooks/scripts/hook-payload.js +64 -0
  231. package/hooks/scripts/lib/dispatcher.js +20 -0
  232. package/hooks/scripts/llm-orchestrate.js +40 -44
  233. package/hooks/scripts/prompt-dispatcher.js +9 -9
  234. package/hooks/scripts/stop-notify.js +1 -1
  235. package/hooks/scripts/utils.js +1 -1
  236. package/package.json +1 -1
  237. package/skills/brand-assets/SKILL.md +11 -11
  238. package/skills/docs/SKILL.md +10 -5
  239. package/skills/event-comms/SKILL.md +1 -1
  240. package/skills/event-ops/SKILL.md +4 -4
  241. package/skills/spec/SKILL.md +29 -29
  242. package/skills/spec-review/SKILL.md +23 -23
  243. package/skills/tool-fallback/SKILL.md +2 -2
  244. package/skills/tool-fallback/rubrics/fallback-chain.md +2 -2
  245. package/skills/vibe.event/SKILL.md +1 -1
  246. package/skills/vibe.review/SKILL.md +13 -13
  247. package/skills/vibe.run/SKILL.md +30 -30
  248. package/skills/vibe.spec/SKILL.md +4 -4
  249. package/skills/vibe.utils/SKILL.md +17 -17
  250. package/hooks/gemini-hooks.json +0 -73
@@ -0,0 +1,73 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/session-start.js"
6
+ }
7
+ ],
8
+ "BeforeTool": [
9
+ {
10
+ "tool_name": "shell",
11
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/sentinel-guard.js Bash"
12
+ },
13
+ {
14
+ "tool_name": "shell",
15
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/pre-tool-guard.js Bash"
16
+ },
17
+ {
18
+ "tool_name": "edit",
19
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/sentinel-guard.js Edit"
20
+ },
21
+ {
22
+ "tool_name": "edit",
23
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/pre-tool-guard.js Edit"
24
+ },
25
+ {
26
+ "tool_name": "write_file",
27
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/sentinel-guard.js Write"
28
+ },
29
+ {
30
+ "tool_name": "write_file",
31
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/pre-tool-guard.js Write"
32
+ }
33
+ ],
34
+ "AfterTool": [
35
+ {
36
+ "tool_name": "edit",
37
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/code-check.js"
38
+ },
39
+ {
40
+ "tool_name": "write_file",
41
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/code-check.js"
42
+ },
43
+ {
44
+ "tool_name": "edit",
45
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/post-edit.js"
46
+ }
47
+ ],
48
+ "BeforeAgent": [
49
+ {
50
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/prompt-dispatcher.js"
51
+ }
52
+ ],
53
+ "Notification": [
54
+ {
55
+ "matcher": "context_window_80",
56
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/context-save.js medium"
57
+ },
58
+ {
59
+ "matcher": "context_window_90",
60
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/context-save.js high"
61
+ },
62
+ {
63
+ "matcher": "context_window_95",
64
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/context-save.js critical"
65
+ }
66
+ ],
67
+ "SessionEnd": [
68
+ {
69
+ "command": "VIBE_CLI=antigravity node {{VIBE_PATH}}/hooks/scripts/stop-notify.js"
70
+ }
71
+ ]
72
+ }
73
+ }
@@ -0,0 +1,31 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { spawnSync } from 'child_process';
3
+ import fs from 'fs';
4
+ import os from 'os';
5
+ import path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const ADAPTER = path.resolve(__dirname, '..', 'codex-hook-adapter.js');
10
+
11
+ describe('codex-hook-adapter', () => {
12
+ it('converts a PreToolUse denial into Codex permission output', () => {
13
+ const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-codex-adapter-'));
14
+ const payload = JSON.stringify({
15
+ tool_name: 'Bash',
16
+ tool_input: { command: 'rm -rf /' },
17
+ });
18
+
19
+ const result = spawnSync(process.execPath, [ADAPTER, 'PreToolUse'], {
20
+ cwd,
21
+ input: payload,
22
+ encoding: 'utf-8',
23
+ timeout: 5000,
24
+ });
25
+
26
+ expect(result.status).toBe(2);
27
+ const output = JSON.parse(result.stdout.trim());
28
+ expect(output.hookSpecificOutput.permissionDecision).toBe('deny');
29
+ expect(output.hookSpecificOutput.permissionDecisionReason).toContain('Deleting root or home directory');
30
+ });
31
+ });
@@ -0,0 +1,29 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ extractToolInput,
4
+ extractToolName,
5
+ normalizeHookPayload,
6
+ } from '../hook-payload.js';
7
+
8
+ describe('hook-payload', () => {
9
+ it('normalizes stdin JSON payloads from native hook runners', () => {
10
+ const payload = normalizeHookPayload(
11
+ JSON.stringify({
12
+ tool_name: 'Bash',
13
+ tool_input: { command: 'npm test' },
14
+ }),
15
+ {},
16
+ );
17
+
18
+ expect(extractToolName(payload)).toBe('Bash');
19
+ expect(extractToolInput(payload).command).toBe('npm test');
20
+ });
21
+
22
+ it('falls back to legacy TOOL_INPUT env for Claude-style scripts', () => {
23
+ const payload = normalizeHookPayload('', {
24
+ TOOL_INPUT: JSON.stringify({ command: 'npm run build' }),
25
+ });
26
+
27
+ expect(extractToolInput(payload).command).toBe('npm run build');
28
+ });
29
+ });
@@ -0,0 +1,63 @@
1
+ import { describe, it, expect, afterEach } from 'vitest';
2
+ import fs from 'fs';
3
+ import os from 'os';
4
+ import path from 'path';
5
+ import { execFileSync } from 'child_process';
6
+
7
+ describe('llm-orchestrate Antigravity provider', () => {
8
+ const tempDirs = [];
9
+
10
+ afterEach(() => {
11
+ for (const dir of tempDirs.splice(0)) {
12
+ fs.rmSync(dir, { recursive: true, force: true });
13
+ }
14
+ });
15
+
16
+ it('calls agy -p for Antigravity text orchestration', () => {
17
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'vibe-agy-'));
18
+ const binDir = path.join(root, 'bin');
19
+ const homeDir = path.join(root, 'home');
20
+ const capturePath = path.join(root, 'capture.json');
21
+ fs.mkdirSync(binDir, { recursive: true });
22
+ fs.mkdirSync(homeDir, { recursive: true });
23
+ tempDirs.push(root);
24
+
25
+ fs.writeFileSync(
26
+ path.join(binDir, 'agy'),
27
+ [
28
+ `#!${process.execPath}`,
29
+ 'const fs = require("fs");',
30
+ 'const stdin = fs.readFileSync(0, "utf8");',
31
+ 'fs.writeFileSync(process.env.AGY_CAPTURE, JSON.stringify({ argv: process.argv.slice(2), stdin }));',
32
+ 'process.stdout.write("antigravity ok");',
33
+ '',
34
+ ].join('\n'),
35
+ { mode: 0o755 }
36
+ );
37
+
38
+ const scriptPath = path.resolve('hooks/scripts/llm-orchestrate.js');
39
+ const output = execFileSync(
40
+ process.execPath,
41
+ [scriptPath, 'antigravity', 'orchestrate-json', 'System prompt', 'User prompt'],
42
+ {
43
+ cwd: root,
44
+ env: {
45
+ ...process.env,
46
+ HOME: homeDir,
47
+ PATH: `${binDir}:${process.env.PATH || ''}`,
48
+ AGY_CAPTURE: capturePath,
49
+ },
50
+ encoding: 'utf8',
51
+ timeout: 5000,
52
+ }
53
+ );
54
+
55
+ const capture = JSON.parse(fs.readFileSync(capturePath, 'utf8'));
56
+ expect(output).toContain('Antigravity response: antigravity ok');
57
+ expect(capture.argv[0]).toBe('-p');
58
+ expect(capture.argv[1]).toContain('[System]\nSystem prompt');
59
+ expect(capture.argv[1]).toContain('[User]\nUser prompt');
60
+ expect(capture.argv[1]).toContain('valid JSON only');
61
+ expect(capture.stdin).toBe('');
62
+ });
63
+ });
@@ -0,0 +1,124 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Codex native hook adapter.
4
+ *
5
+ * Maps Codex hook events to the existing vibe hook scripts while preserving
6
+ * Codex JSON decisions for permission-deny cases.
7
+ */
8
+ import { spawnSync } from 'child_process';
9
+ import path from 'path';
10
+ import { fileURLToPath } from 'url';
11
+ import {
12
+ extractPrompt,
13
+ extractToolInput,
14
+ extractToolName,
15
+ normalizeHookPayload,
16
+ readStdinSync,
17
+ } from './hook-payload.js';
18
+
19
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
20
+ const eventName = process.argv[2] || '';
21
+ const stdinData = readStdinSync();
22
+ const payload = normalizeHookPayload(stdinData, process.env);
23
+
24
+ if (process.env.VIBE_HOOK_DEPTH) process.exit(0);
25
+
26
+ function toolInputJson() {
27
+ return JSON.stringify(extractToolInput(payload));
28
+ }
29
+
30
+ function childEnv() {
31
+ return {
32
+ ...process.env,
33
+ HOOK_INPUT: stdinData || JSON.stringify(payload),
34
+ TOOL_INPUT: toolInputJson(),
35
+ };
36
+ }
37
+
38
+ function runScript(scriptName, args = []) {
39
+ const scriptPath = path.join(__dirname, scriptName);
40
+ return spawnSync(process.execPath, [scriptPath, ...args], {
41
+ input: stdinData || JSON.stringify(payload),
42
+ encoding: 'utf-8',
43
+ env: childEnv(),
44
+ timeout: 30000,
45
+ });
46
+ }
47
+
48
+ function combinedOutput(result) {
49
+ return `${result.stdout || ''}${result.stderr || ''}`.trim();
50
+ }
51
+
52
+ function writeJson(value) {
53
+ process.stdout.write(`${JSON.stringify(value)}\n`);
54
+ }
55
+
56
+ function writeAdditionalContext(text) {
57
+ if (!text) return;
58
+ writeJson({
59
+ hookSpecificOutput: {
60
+ hookEventName: eventName,
61
+ additionalContext: text,
62
+ },
63
+ });
64
+ }
65
+
66
+ function mappedToolName() {
67
+ const toolName = extractToolName(payload, '');
68
+ if (toolName === 'apply_patch') return 'Edit';
69
+ if (toolName === 'shell') return 'Bash';
70
+ return toolName;
71
+ }
72
+
73
+ function handlePreToolUse() {
74
+ const result = runScript('pre-tool-dispatcher.js', [mappedToolName()]);
75
+ const output = combinedOutput(result);
76
+ if (result.status === 2) {
77
+ writeJson({
78
+ hookSpecificOutput: {
79
+ hookEventName: 'PreToolUse',
80
+ permissionDecision: 'deny',
81
+ permissionDecisionReason: output || 'vibe pre-tool guard denied this operation',
82
+ },
83
+ });
84
+ process.exit(2);
85
+ }
86
+ writeAdditionalContext(output);
87
+ }
88
+
89
+ function handleUserPromptSubmit() {
90
+ if (!extractPrompt(payload)) return;
91
+ const result = runScript('prompt-dispatcher.js');
92
+ writeAdditionalContext(combinedOutput(result));
93
+ }
94
+
95
+ function handlePostToolUse() {
96
+ const result = runScript('post-edit-dispatcher.js');
97
+ writeAdditionalContext(combinedOutput(result));
98
+ }
99
+
100
+ function handleStop() {
101
+ // Turn-complete side effects stay on Codex notify to avoid duplicate commits.
102
+ }
103
+
104
+ switch (eventName) {
105
+ case 'SessionStart':
106
+ writeAdditionalContext(combinedOutput(runScript('session-start.js')));
107
+ break;
108
+ case 'UserPromptSubmit':
109
+ handleUserPromptSubmit();
110
+ break;
111
+ case 'PreToolUse':
112
+ handlePreToolUse();
113
+ break;
114
+ case 'PostToolUse':
115
+ handlePostToolUse();
116
+ break;
117
+ case 'Stop':
118
+ handleStop();
119
+ break;
120
+ default:
121
+ break;
122
+ }
123
+
124
+ process.exit(0);
@@ -28,7 +28,7 @@ for await (const chunk of process.stdin) {
28
28
 
29
29
  // Codex CLI/플러그인 설치 여부 확인
30
30
  function isCodexAvailable() {
31
- const codexDir = path.join(os.homedir(), '.codex');
31
+ const codexDir = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
32
32
  if (fs.existsSync(codexDir)) return true;
33
33
 
34
34
  try {
@@ -42,8 +42,12 @@ function isCodexAvailable() {
42
42
  // 프로젝트 config에서 codexReviewGate 설정 확인
43
43
  function isCodexReviewGateEnabled() {
44
44
  try {
45
- const configPath = path.join(process.cwd(), '.claude', 'vibe', 'config.json');
46
- if (!fs.existsSync(configPath)) return true; // 기본: 활성화
45
+ const candidates = [
46
+ path.join(process.cwd(), '.vibe', 'config.json'),
47
+ path.join(process.cwd(), '.claude', 'vibe', 'config.json'),
48
+ ];
49
+ const configPath = candidates.find(p => fs.existsSync(p));
50
+ if (!configPath) return true; // 기본: 활성화
47
51
  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
48
52
  // 명시적으로 false일 때만 비활성화
49
53
  return config.codexReviewGate !== false;
@@ -4,7 +4,7 @@
4
4
  * 매 커밋 후 카운터를 확인하여 interval(기본 10)에 도달하면
5
5
  * LLM을 통해 개발일지를 생성하고 설정된 블로그 레포에 저장합니다.
6
6
  *
7
- * Config: .claude/vibe/config.json → devlog 섹션
7
+ * Config: .vibe/config.json → devlog 섹션
8
8
  */
9
9
  import { execSync } from 'child_process';
10
10
  import fs from 'fs';
@@ -0,0 +1,64 @@
1
+ import fs from 'fs';
2
+
3
+ function parseJson(raw) {
4
+ if (!raw || typeof raw !== 'string') return null;
5
+ try {
6
+ return JSON.parse(raw);
7
+ } catch {
8
+ return null;
9
+ }
10
+ }
11
+
12
+ function asObject(value) {
13
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
14
+ }
15
+
16
+ export function normalizeHookPayload(stdinData = '', env = process.env) {
17
+ const stdinPayload = parseJson(stdinData);
18
+ if (stdinPayload) return asObject(stdinPayload);
19
+
20
+ const hookPayload = parseJson(env.HOOK_INPUT || '');
21
+ if (hookPayload) return asObject(hookPayload);
22
+
23
+ const toolInput = parseJson(env.TOOL_INPUT || '');
24
+ if (toolInput) return { tool_input: asObject(toolInput) };
25
+
26
+ return {};
27
+ }
28
+
29
+ export function readStdinSync() {
30
+ try {
31
+ if (process.stdin.isTTY) return '';
32
+ const chunks = [];
33
+ const buffer = Buffer.alloc(65536);
34
+ let bytesRead = 0;
35
+ do {
36
+ bytesRead = fs.readSync(0, buffer, 0, buffer.length, null);
37
+ if (bytesRead > 0) chunks.push(buffer.subarray(0, bytesRead));
38
+ } while (bytesRead === buffer.length);
39
+ return Buffer.concat(chunks).toString('utf-8');
40
+ } catch {
41
+ return '';
42
+ }
43
+ }
44
+
45
+ export function readHookPayloadSync() {
46
+ return normalizeHookPayload(readStdinSync(), process.env);
47
+ }
48
+
49
+ export function extractToolInput(payload) {
50
+ const fallbackInput = payload?.input && typeof payload.input === 'object' ? payload.input : {};
51
+ const input = payload?.tool_input ?? payload?.toolInput ?? fallbackInput;
52
+ if (typeof input === 'string') return asObject(parseJson(input));
53
+ return asObject(input);
54
+ }
55
+
56
+ export function extractToolName(payload, fallback = '') {
57
+ const name = payload?.tool_name ?? payload?.toolName ?? payload?.tool;
58
+ return typeof name === 'string' ? name : fallback;
59
+ }
60
+
61
+ export function extractPrompt(payload) {
62
+ const prompt = payload?.prompt ?? payload?.user_prompt ?? payload?.input;
63
+ return typeof prompt === 'string' ? prompt : '';
64
+ }
@@ -60,9 +60,11 @@ async function readStdin() {
60
60
  function runScript(scriptName, args, stdinData, timeoutMs) {
61
61
  return new Promise((resolve) => {
62
62
  const scriptPath = path.join(SCRIPTS_DIR, scriptName);
63
+ const env = buildChildEnv(stdinData);
63
64
  const proc = spawn(process.execPath, [scriptPath, ...args], {
64
65
  stdio: ['pipe', 'inherit', 'inherit'],
65
66
  timeout: timeoutMs,
67
+ env,
66
68
  });
67
69
  if (stdinData) proc.stdin.end(stdinData);
68
70
  else proc.stdin.end();
@@ -71,6 +73,24 @@ function runScript(scriptName, args, stdinData, timeoutMs) {
71
73
  });
72
74
  }
73
75
 
76
+ function buildChildEnv(stdinData) {
77
+ const env = { ...process.env };
78
+ if (!stdinData) return env;
79
+
80
+ env.HOOK_INPUT = stdinData;
81
+ try {
82
+ const parsed = JSON.parse(stdinData);
83
+ if (parsed?.tool_input) {
84
+ env.TOOL_INPUT = typeof parsed.tool_input === 'string'
85
+ ? parsed.tool_input
86
+ : JSON.stringify(parsed.tool_input);
87
+ }
88
+ } catch {
89
+ // Leave legacy env untouched when stdin is not JSON.
90
+ }
91
+ return env;
92
+ }
93
+
74
94
  /**
75
95
  * 디스패처 실행 — 활성화된 스텝을 병렬로 spawn.
76
96
  * @param {Array<{name: string, script: string, args?: string[], denyOnExit2?: boolean, timeoutMs?: number}>} steps