@nocville/npc 0.0.0-stage → 0.2.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 (213) hide show
  1. package/README.md +268 -2
  2. package/dist/cjs/cli.js +584 -0
  3. package/dist/cjs/core/api-key.js +69 -0
  4. package/dist/cjs/core/base-npc.js +160 -0
  5. package/dist/cjs/core/config.js +108 -0
  6. package/dist/cjs/core/event-npc.js +14 -0
  7. package/dist/cjs/core/logger.js +39 -0
  8. package/dist/cjs/core/polling-npc.js +65 -0
  9. package/dist/cjs/core/screen.js +28 -0
  10. package/dist/cjs/core/session-filter.js +150 -0
  11. package/dist/cjs/core/text.js +15 -0
  12. package/dist/cjs/core/thresholds.js +48 -0
  13. package/dist/cjs/core/types.js +10 -0
  14. package/dist/cjs/core/user-config.js +92 -0
  15. package/dist/cjs/doctor.js +130 -0
  16. package/dist/cjs/index.js +95 -0
  17. package/dist/cjs/npcs/agent-common/activity.js +291 -0
  18. package/dist/cjs/npcs/agent-common/git-stats.js +71 -0
  19. package/dist/cjs/npcs/agent-common/hook-runner.js +252 -0
  20. package/dist/cjs/npcs/agent-common/hook-settings.js +279 -0
  21. package/dist/cjs/npcs/agent-common/liveness.js +112 -0
  22. package/dist/cjs/npcs/agent-common/lock.js +99 -0
  23. package/dist/cjs/npcs/agent-common/runtime.js +154 -0
  24. package/dist/cjs/npcs/agent-common/session.js +412 -0
  25. package/dist/cjs/npcs/agent-common/shim.js +96 -0
  26. package/dist/cjs/npcs/agent-common/watchdog.js +149 -0
  27. package/dist/cjs/npcs/claude-code/defaults.js +20 -0
  28. package/dist/cjs/npcs/claude-code/hook-handler.js +139 -0
  29. package/dist/cjs/npcs/claude-code/index.js +104 -0
  30. package/dist/cjs/npcs/claude-code/setup.js +133 -0
  31. package/dist/cjs/npcs/claude-code/state-machine.js +130 -0
  32. package/dist/cjs/npcs/codex/defaults.js +32 -0
  33. package/dist/cjs/npcs/codex/hook-handler.js +116 -0
  34. package/dist/cjs/npcs/codex/index.js +92 -0
  35. package/dist/cjs/npcs/codex/rollout.js +246 -0
  36. package/dist/cjs/npcs/codex/setup.js +104 -0
  37. package/dist/cjs/npcs/codex/watcher.js +361 -0
  38. package/dist/cjs/npcs/cursor/defaults.js +15 -0
  39. package/dist/cjs/npcs/cursor/hook-handler.js +65 -0
  40. package/dist/cjs/npcs/cursor/index.js +72 -0
  41. package/dist/cjs/npcs/cursor/normalize.js +54 -0
  42. package/dist/cjs/npcs/cursor/setup.js +98 -0
  43. package/dist/cjs/npcs/gemini/defaults.js +15 -0
  44. package/dist/cjs/npcs/gemini/hook-handler.js +93 -0
  45. package/dist/cjs/npcs/gemini/index.js +69 -0
  46. package/dist/cjs/npcs/gemini/setup.js +98 -0
  47. package/dist/cjs/npcs/github-watcher/defaults.js +11 -0
  48. package/dist/cjs/npcs/github-watcher/format.js +21 -0
  49. package/dist/cjs/npcs/github-watcher/github-api.js +126 -0
  50. package/dist/cjs/npcs/github-watcher/index.js +148 -0
  51. package/dist/cjs/npcs/internet-connectivity/checks.js +92 -0
  52. package/dist/cjs/npcs/internet-connectivity/defaults.js +22 -0
  53. package/dist/cjs/npcs/internet-connectivity/index.js +251 -0
  54. package/dist/cjs/npcs/log-watcher/buffer.js +40 -0
  55. package/dist/cjs/npcs/log-watcher/defaults.js +12 -0
  56. package/dist/cjs/npcs/log-watcher/index.js +161 -0
  57. package/dist/cjs/npcs/log-watcher/tail.js +81 -0
  58. package/dist/cjs/npcs/process-watcher/defaults.js +9 -0
  59. package/dist/cjs/npcs/process-watcher/index.js +140 -0
  60. package/dist/cjs/npcs/process-watcher/process-scanner.js +114 -0
  61. package/dist/cjs/npcs/receptionist/defaults.js +9 -0
  62. package/dist/cjs/npcs/receptionist/index.js +120 -0
  63. package/dist/cjs/npcs/receptionist/weather.js +129 -0
  64. package/dist/cjs/npcs/system-monitor/collectors.js +68 -0
  65. package/dist/cjs/npcs/system-monitor/defaults.js +13 -0
  66. package/dist/cjs/npcs/system-monitor/index.js +105 -0
  67. package/dist/cjs/npcs/web-page-watcher/basic-mode.js +58 -0
  68. package/dist/cjs/npcs/web-page-watcher/capture.js +80 -0
  69. package/dist/cjs/npcs/web-page-watcher/defaults.js +31 -0
  70. package/dist/cjs/npcs/web-page-watcher/index.js +234 -0
  71. package/dist/cjs/npcs/web-page-watcher/pixelate.js +181 -0
  72. package/dist/cjs/package.json +1 -0
  73. package/dist/cli.d.ts +3 -0
  74. package/dist/cli.js +549 -0
  75. package/dist/core/api-key.d.ts +34 -0
  76. package/dist/core/api-key.js +64 -0
  77. package/dist/core/base-npc.d.ts +41 -0
  78. package/dist/core/base-npc.js +156 -0
  79. package/dist/core/config.d.ts +22 -0
  80. package/dist/core/config.js +101 -0
  81. package/dist/core/event-npc.d.ts +8 -0
  82. package/dist/core/event-npc.js +10 -0
  83. package/dist/core/logger.d.ts +11 -0
  84. package/dist/core/logger.js +35 -0
  85. package/dist/core/polling-npc.d.ts +18 -0
  86. package/dist/core/polling-npc.js +61 -0
  87. package/dist/core/screen.d.ts +11 -0
  88. package/dist/core/screen.js +24 -0
  89. package/dist/core/session-filter.d.ts +59 -0
  90. package/dist/core/session-filter.js +143 -0
  91. package/dist/core/text.d.ts +6 -0
  92. package/dist/core/text.js +12 -0
  93. package/dist/core/thresholds.d.ts +10 -0
  94. package/dist/core/thresholds.js +44 -0
  95. package/dist/core/types.d.ts +60 -0
  96. package/dist/core/types.js +7 -0
  97. package/dist/core/user-config.d.ts +43 -0
  98. package/dist/core/user-config.js +85 -0
  99. package/dist/doctor.d.ts +8 -0
  100. package/dist/doctor.js +126 -0
  101. package/dist/index.d.ts +41 -0
  102. package/dist/index.js +26 -0
  103. package/dist/npcs/agent-common/activity.d.ts +42 -0
  104. package/dist/npcs/agent-common/activity.js +280 -0
  105. package/dist/npcs/agent-common/git-stats.d.ts +11 -0
  106. package/dist/npcs/agent-common/git-stats.js +67 -0
  107. package/dist/npcs/agent-common/hook-runner.d.ts +62 -0
  108. package/dist/npcs/agent-common/hook-runner.js +245 -0
  109. package/dist/npcs/agent-common/hook-settings.d.ts +75 -0
  110. package/dist/npcs/agent-common/hook-settings.js +265 -0
  111. package/dist/npcs/agent-common/liveness.d.ts +12 -0
  112. package/dist/npcs/agent-common/liveness.js +105 -0
  113. package/dist/npcs/agent-common/lock.d.ts +6 -0
  114. package/dist/npcs/agent-common/lock.js +95 -0
  115. package/dist/npcs/agent-common/runtime.d.ts +16 -0
  116. package/dist/npcs/agent-common/runtime.js +149 -0
  117. package/dist/npcs/agent-common/session.d.ts +192 -0
  118. package/dist/npcs/agent-common/session.js +390 -0
  119. package/dist/npcs/agent-common/shim.d.ts +4 -0
  120. package/dist/npcs/agent-common/shim.js +90 -0
  121. package/dist/npcs/agent-common/watchdog.d.ts +16 -0
  122. package/dist/npcs/agent-common/watchdog.js +144 -0
  123. package/dist/npcs/claude-code/defaults.d.ts +15 -0
  124. package/dist/npcs/claude-code/defaults.js +17 -0
  125. package/dist/npcs/claude-code/hook-handler.d.ts +40 -0
  126. package/dist/npcs/claude-code/hook-handler.js +131 -0
  127. package/dist/npcs/claude-code/index.d.ts +36 -0
  128. package/dist/npcs/claude-code/index.js +92 -0
  129. package/dist/npcs/claude-code/setup.d.ts +58 -0
  130. package/dist/npcs/claude-code/setup.js +121 -0
  131. package/dist/npcs/claude-code/state-machine.d.ts +28 -0
  132. package/dist/npcs/claude-code/state-machine.js +125 -0
  133. package/dist/npcs/codex/defaults.d.ts +24 -0
  134. package/dist/npcs/codex/defaults.js +28 -0
  135. package/dist/npcs/codex/hook-handler.d.ts +24 -0
  136. package/dist/npcs/codex/hook-handler.js +110 -0
  137. package/dist/npcs/codex/index.d.ts +21 -0
  138. package/dist/npcs/codex/index.js +76 -0
  139. package/dist/npcs/codex/rollout.d.ts +39 -0
  140. package/dist/npcs/codex/rollout.js +242 -0
  141. package/dist/npcs/codex/setup.d.ts +37 -0
  142. package/dist/npcs/codex/setup.js +96 -0
  143. package/dist/npcs/codex/watcher.d.ts +65 -0
  144. package/dist/npcs/codex/watcher.js +356 -0
  145. package/dist/npcs/cursor/defaults.d.ts +9 -0
  146. package/dist/npcs/cursor/defaults.js +11 -0
  147. package/dist/npcs/cursor/hook-handler.d.ts +8 -0
  148. package/dist/npcs/cursor/hook-handler.js +60 -0
  149. package/dist/npcs/cursor/index.d.ts +18 -0
  150. package/dist/npcs/cursor/index.js +57 -0
  151. package/dist/npcs/cursor/normalize.d.ts +6 -0
  152. package/dist/npcs/cursor/normalize.js +49 -0
  153. package/dist/npcs/cursor/setup.d.ts +29 -0
  154. package/dist/npcs/cursor/setup.js +90 -0
  155. package/dist/npcs/gemini/defaults.d.ts +9 -0
  156. package/dist/npcs/gemini/defaults.js +11 -0
  157. package/dist/npcs/gemini/hook-handler.d.ts +10 -0
  158. package/dist/npcs/gemini/hook-handler.js +87 -0
  159. package/dist/npcs/gemini/index.d.ts +17 -0
  160. package/dist/npcs/gemini/index.js +56 -0
  161. package/dist/npcs/gemini/setup.d.ts +29 -0
  162. package/dist/npcs/gemini/setup.js +90 -0
  163. package/dist/npcs/github-watcher/defaults.d.ts +8 -0
  164. package/dist/npcs/github-watcher/defaults.js +8 -0
  165. package/dist/npcs/github-watcher/format.d.ts +3 -0
  166. package/dist/npcs/github-watcher/format.js +18 -0
  167. package/dist/npcs/github-watcher/github-api.d.ts +55 -0
  168. package/dist/npcs/github-watcher/github-api.js +120 -0
  169. package/dist/npcs/github-watcher/index.d.ts +35 -0
  170. package/dist/npcs/github-watcher/index.js +144 -0
  171. package/dist/npcs/internet-connectivity/checks.d.ts +24 -0
  172. package/dist/npcs/internet-connectivity/checks.js +84 -0
  173. package/dist/npcs/internet-connectivity/defaults.d.ts +20 -0
  174. package/dist/npcs/internet-connectivity/defaults.js +19 -0
  175. package/dist/npcs/internet-connectivity/index.d.ts +55 -0
  176. package/dist/npcs/internet-connectivity/index.js +246 -0
  177. package/dist/npcs/log-watcher/buffer.d.ts +18 -0
  178. package/dist/npcs/log-watcher/buffer.js +34 -0
  179. package/dist/npcs/log-watcher/defaults.d.ts +9 -0
  180. package/dist/npcs/log-watcher/defaults.js +9 -0
  181. package/dist/npcs/log-watcher/index.d.ts +45 -0
  182. package/dist/npcs/log-watcher/index.js +157 -0
  183. package/dist/npcs/log-watcher/tail.d.ts +9 -0
  184. package/dist/npcs/log-watcher/tail.js +78 -0
  185. package/dist/npcs/process-watcher/defaults.d.ts +6 -0
  186. package/dist/npcs/process-watcher/defaults.js +6 -0
  187. package/dist/npcs/process-watcher/index.d.ts +26 -0
  188. package/dist/npcs/process-watcher/index.js +136 -0
  189. package/dist/npcs/process-watcher/process-scanner.d.ts +19 -0
  190. package/dist/npcs/process-watcher/process-scanner.js +110 -0
  191. package/dist/npcs/receptionist/defaults.d.ts +6 -0
  192. package/dist/npcs/receptionist/defaults.js +6 -0
  193. package/dist/npcs/receptionist/index.d.ts +29 -0
  194. package/dist/npcs/receptionist/index.js +116 -0
  195. package/dist/npcs/receptionist/weather.d.ts +37 -0
  196. package/dist/npcs/receptionist/weather.js +121 -0
  197. package/dist/npcs/system-monitor/collectors.d.ts +45 -0
  198. package/dist/npcs/system-monitor/collectors.js +60 -0
  199. package/dist/npcs/system-monitor/defaults.d.ts +7 -0
  200. package/dist/npcs/system-monitor/defaults.js +10 -0
  201. package/dist/npcs/system-monitor/index.d.ts +27 -0
  202. package/dist/npcs/system-monitor/index.js +101 -0
  203. package/dist/npcs/web-page-watcher/basic-mode.d.ts +16 -0
  204. package/dist/npcs/web-page-watcher/basic-mode.js +52 -0
  205. package/dist/npcs/web-page-watcher/capture.d.ts +49 -0
  206. package/dist/npcs/web-page-watcher/capture.js +75 -0
  207. package/dist/npcs/web-page-watcher/defaults.d.ts +19 -0
  208. package/dist/npcs/web-page-watcher/defaults.js +27 -0
  209. package/dist/npcs/web-page-watcher/index.d.ts +42 -0
  210. package/dist/npcs/web-page-watcher/index.js +230 -0
  211. package/dist/npcs/web-page-watcher/pixelate.d.ts +36 -0
  212. package/dist/npcs/web-page-watcher/pixelate.js +172 -0
  213. package/package.json +73 -3
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CodexWatcher = exports.describeExecScript = exports.parseRolloutLine = exports.CODEX_HOOK_EVENTS = exports.installCodexHooksInto = exports.uninstallCodexHooks = exports.setupCodexHooks = exports.handleCodexHookEvent = exports.codexServiceId = exports.codexTransition = exports.CODEX_ADAPTER = exports.CODEX_DEFAULTS = void 0;
4
+ exports.handleCodexCommand = handleCodexCommand;
5
+ const config_js_1 = require("../../core/config.js");
6
+ const hook_runner_js_1 = require("../agent-common/hook-runner.js");
7
+ const watchdog_js_1 = require("../agent-common/watchdog.js");
8
+ const session_js_1 = require("../agent-common/session.js");
9
+ const defaults_js_1 = require("./defaults.js");
10
+ const hook_handler_js_1 = require("./hook-handler.js");
11
+ const setup_js_1 = require("./setup.js");
12
+ const watcher_js_1 = require("./watcher.js");
13
+ var defaults_js_2 = require("./defaults.js");
14
+ Object.defineProperty(exports, "CODEX_DEFAULTS", { enumerable: true, get: function () { return defaults_js_2.CODEX_DEFAULTS; } });
15
+ var hook_handler_js_2 = require("./hook-handler.js");
16
+ Object.defineProperty(exports, "CODEX_ADAPTER", { enumerable: true, get: function () { return hook_handler_js_2.CODEX_ADAPTER; } });
17
+ Object.defineProperty(exports, "codexTransition", { enumerable: true, get: function () { return hook_handler_js_2.codexTransition; } });
18
+ Object.defineProperty(exports, "codexServiceId", { enumerable: true, get: function () { return hook_handler_js_2.codexServiceId; } });
19
+ Object.defineProperty(exports, "handleCodexHookEvent", { enumerable: true, get: function () { return hook_handler_js_2.handleCodexHookEvent; } });
20
+ var setup_js_2 = require("./setup.js");
21
+ Object.defineProperty(exports, "setupCodexHooks", { enumerable: true, get: function () { return setup_js_2.setupCodexHooks; } });
22
+ Object.defineProperty(exports, "uninstallCodexHooks", { enumerable: true, get: function () { return setup_js_2.uninstallCodexHooks; } });
23
+ Object.defineProperty(exports, "installCodexHooksInto", { enumerable: true, get: function () { return setup_js_2.installCodexHooksInto; } });
24
+ Object.defineProperty(exports, "CODEX_HOOK_EVENTS", { enumerable: true, get: function () { return setup_js_2.CODEX_HOOK_EVENTS; } });
25
+ var rollout_js_1 = require("./rollout.js");
26
+ Object.defineProperty(exports, "parseRolloutLine", { enumerable: true, get: function () { return rollout_js_1.parseRolloutLine; } });
27
+ Object.defineProperty(exports, "describeExecScript", { enumerable: true, get: function () { return rollout_js_1.describeExecScript; } });
28
+ var watcher_js_2 = require("./watcher.js");
29
+ Object.defineProperty(exports, "CodexWatcher", { enumerable: true, get: function () { return watcher_js_2.CodexWatcher; } });
30
+ /**
31
+ * codex subcommands: setup | uninstall | hook | flush | watch | cleanup.
32
+ * `hook`/`flush` are invoked by Codex / ourselves and stay silent on stdout.
33
+ */
34
+ async function handleCodexCommand(opts) {
35
+ const { subcommand, config, flags } = opts;
36
+ switch (subcommand) {
37
+ case 'setup': {
38
+ if (flags['uninstall']) {
39
+ (0, setup_js_1.uninstallCodexHooks)();
40
+ break;
41
+ }
42
+ const ok = (0, setup_js_1.setupCodexHooks)({
43
+ apiUrl: (0, config_js_1.stringFlag)(flags, 'api-url') ?? process.env['NOCVILLE_API_URL'],
44
+ apiKey: (0, config_js_1.stringFlag)(flags, 'api-key') ?? process.env['NOCVILLE_API_KEY'],
45
+ map: (0, config_js_1.stringFlag)(flags, 'map'),
46
+ cliPath: process.argv[1],
47
+ });
48
+ if (!ok)
49
+ process.exitCode = 1;
50
+ break;
51
+ }
52
+ case 'uninstall':
53
+ (0, setup_js_1.uninstallCodexHooks)();
54
+ break;
55
+ case 'hook':
56
+ await (0, hook_handler_js_1.handleCodexHookEvent)(config, (0, hook_runner_js_1.readStdin)(), { mode: 'detach' });
57
+ break;
58
+ case 'watchdog':
59
+ await (0, watchdog_js_1.runWatchdog)(hook_handler_js_1.CODEX_ADAPTER, config, opts.args?.[0]);
60
+ break;
61
+ case 'flush':
62
+ await (0, hook_runner_js_1.runFlushCommand)(hook_handler_js_1.CODEX_ADAPTER, config, opts.args?.[0], (0, config_js_1.numberFlag)(flags, 'delay'), flags['stats'] === true);
63
+ break;
64
+ case 'watch': {
65
+ console.error('codex watch is a fallback for Codex builds without hooks; prefer `nocville-npc codex setup`.');
66
+ if (!config.apiKey) {
67
+ console.error('Error: no API key — run `nocville-npc init --api-key=<key>` or pass --api-key');
68
+ process.exitCode = 1;
69
+ return;
70
+ }
71
+ const idleMin = (0, config_js_1.numberFlag)(flags, 'idle-timeout');
72
+ const watcher = new watcher_js_1.CodexWatcher(config, {
73
+ sessionsDir: (0, config_js_1.stringFlag)(flags, 'sessions-dir'),
74
+ idleTimeoutMs: idleMin !== undefined ? idleMin * 60_000 : undefined,
75
+ includeExec: (0, config_js_1.boolFlag)(flags, 'include-exec') ?? false,
76
+ pollMs: (0, config_js_1.numberFlag)(flags, 'poll-interval'),
77
+ });
78
+ await watcher.start();
79
+ break;
80
+ }
81
+ case 'cleanup': {
82
+ const removed = await (0, session_js_1.cleanupSessionStates)(defaults_js_1.CODEX_DEFAULTS.stateDir, defaults_js_1.CODEX_DEFAULTS.stateFileMaxAge);
83
+ console.log(`Cleanup complete: ${removed} stale file(s) removed`);
84
+ break;
85
+ }
86
+ default:
87
+ console.error(`Unknown codex subcommand: ${subcommand}`);
88
+ console.error('Available subcommands: setup, uninstall, watch, hook, cleanup');
89
+ process.exitCode = 1;
90
+ }
91
+ }
92
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeExecScript = describeExecScript;
4
+ exports.parseRolloutLine = parseRolloutLine;
5
+ // Unsupported, best-effort fallback: Codex rollout logs are an internal format. Prefer hooks.
6
+ const activity_js_1 = require("../agent-common/activity.js");
7
+ const isObj = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
8
+ const s = (v) => (typeof v === 'string' && v ? v : undefined);
9
+ function stripFileUrl(p) {
10
+ return p.replace(/^file:\/\//, '');
11
+ }
12
+ /** Pull a JS/JSON string property (`cmd:"…"` / `"cmd": "…"`) out of a script. */
13
+ function scriptString(script, key) {
14
+ const re = new RegExp(`["']?${key}["']?\\s*:\\s*"((?:[^"\\\\]|\\\\.)*)"`);
15
+ const m = script.match(re);
16
+ if (!m)
17
+ return undefined;
18
+ try {
19
+ return JSON.parse(`"${m[1]}"`);
20
+ }
21
+ catch {
22
+ return m[1];
23
+ }
24
+ }
25
+ /** Tool helpers inside exec scripts that carry nothing worth showing. */
26
+ const QUIET_SCRIPT_TOOLS = new Set(['write_stdin', 'wait', 'clock__curr_time', 'get_goal']);
27
+ /**
28
+ * Describe a Codex "exec" code-mode script (`text(await tools.exec_command({cmd:"…"}))`)
29
+ * by its first tool call. Returns null for no-op helpers.
30
+ */
31
+ function describeExecScript(script, cwd) {
32
+ const m = script.match(/tools\.([A-Za-z0-9_]+)\s*\(/);
33
+ if (!m)
34
+ return 'Running code';
35
+ const tool = m[1];
36
+ if (QUIET_SCRIPT_TOOLS.has(tool))
37
+ return null;
38
+ switch (tool) {
39
+ case 'exec_command': {
40
+ const cmd = scriptString(script, 'cmd') ?? scriptString(script, 'command');
41
+ const short = cmd ? (0, activity_js_1.shortCommand)(cmd) : '';
42
+ return short ? `Running ${short}` : 'Running a command';
43
+ }
44
+ case 'apply_patch': {
45
+ // The patch is embedded as a JS string with escaped newlines.
46
+ return (0, activity_js_1.editingFiles)((0, activity_js_1.patchFiles)(script.replace(/\\n/g, '\n')), cwd);
47
+ }
48
+ case 'view_image':
49
+ return 'Viewing an image';
50
+ case 'update_plan':
51
+ return 'Planning';
52
+ case 'web__run':
53
+ case 'web_search':
54
+ return 'Browsing the web';
55
+ case 'image_gen__imagegen':
56
+ return 'Generating an image';
57
+ case 'spawn_agent':
58
+ return 'Delegating to a subagent';
59
+ default:
60
+ return (0, activity_js_1.describeToolUse)(tool.includes('__') ? `mcp__${tool}` : tool, {}, cwd);
61
+ }
62
+ }
63
+ function parseArgs(raw) {
64
+ if (isObj(raw))
65
+ return raw;
66
+ if (typeof raw === 'string') {
67
+ try {
68
+ const parsed = JSON.parse(raw);
69
+ if (isObj(parsed))
70
+ return parsed;
71
+ }
72
+ catch {
73
+ return { input: raw };
74
+ }
75
+ }
76
+ return {};
77
+ }
78
+ /** Describe a `function_call` / `custom_tool_call` response item. */
79
+ function describeCall(name, rawArgs, cwd) {
80
+ switch (name) {
81
+ case 'exec':
82
+ return typeof rawArgs === 'string' ? describeExecScript(rawArgs, cwd) : 'Running code';
83
+ case 'wait':
84
+ case 'write_stdin':
85
+ case 'list_agents':
86
+ return null;
87
+ case 'send_message':
88
+ case 'followup_task':
89
+ return 'Coordinating subagents';
90
+ case 'apply_patch': {
91
+ const args = parseArgs(rawArgs);
92
+ const patch = s(args['input']) ?? s(args['patch']) ?? (typeof rawArgs === 'string' ? rawArgs : '');
93
+ return (0, activity_js_1.editingFiles)((0, activity_js_1.patchFiles)(patch), cwd);
94
+ }
95
+ case 'shell':
96
+ case 'local_shell':
97
+ case 'exec_command':
98
+ case 'container.exec': {
99
+ const args = parseArgs(rawArgs);
100
+ return (0, activity_js_1.describeToolUse)('Bash', { command: args['command'] ?? args['cmd'] }, cwd);
101
+ }
102
+ default:
103
+ return (0, activity_js_1.describeToolUse)(name, parseArgs(rawArgs), cwd);
104
+ }
105
+ }
106
+ function approvalText(payload, cwd) {
107
+ const cmd = payload['command'];
108
+ if (cmd) {
109
+ const short = (0, activity_js_1.shortCommand)(cmd);
110
+ if (short)
111
+ return `Needs your approval: Running ${short}`;
112
+ }
113
+ const changes = payload['changes'];
114
+ if (isObj(changes)) {
115
+ return `Needs your approval: ${(0, activity_js_1.editingFiles)(Object.keys(changes).map(stripFileUrl), cwd)}`;
116
+ }
117
+ return 'Needs your approval';
118
+ }
119
+ function parseEventMsg(payload, cwd) {
120
+ const type = s(payload['type']) ?? '';
121
+ switch (type) {
122
+ case 'task_started':
123
+ case 'user_message':
124
+ return { kind: 'working', activity: activity_js_1.THINKING };
125
+ case 'task_complete':
126
+ return { kind: 'idle', activity: 'Done — waiting for next task' };
127
+ case 'turn_aborted':
128
+ return { kind: 'idle', activity: 'Interrupted — waiting for you' };
129
+ case 'exec_command_begin': {
130
+ const short = (0, activity_js_1.shortCommand)(payload['command']);
131
+ return { kind: 'working', activity: short ? `Running ${short}` : 'Running a command' };
132
+ }
133
+ case 'patch_apply_begin': {
134
+ const changes = isObj(payload['changes']) ? Object.keys(payload['changes']) : [];
135
+ return { kind: 'working', activity: (0, activity_js_1.editingFiles)(changes.map(stripFileUrl), cwd) };
136
+ }
137
+ case 'web_search_begin':
138
+ return { kind: 'working', activity: 'Searching the web' };
139
+ case 'request_user_input':
140
+ return { kind: 'waiting', activity: 'Has a question for you' };
141
+ case 'item_started': {
142
+ const item = isObj(payload['item']) ? payload['item'] : {};
143
+ const itemType = s(item['type']);
144
+ if (itemType === 'CommandExecution') {
145
+ const short = (0, activity_js_1.shortCommand)(item['command']);
146
+ return { kind: 'working', activity: short ? `Running ${short}` : 'Running a command' };
147
+ }
148
+ if (itemType === 'FileChange' && isObj(item['changes'])) {
149
+ return {
150
+ kind: 'working',
151
+ activity: (0, activity_js_1.editingFiles)(Object.keys(item['changes']).map(stripFileUrl), cwd),
152
+ };
153
+ }
154
+ return null;
155
+ }
156
+ case 'item_completed': {
157
+ // Newer builds log file edits only on completion; still the best signal.
158
+ const item = isObj(payload['item']) ? payload['item'] : {};
159
+ if (s(item['type']) === 'FileChange' && isObj(item['changes'])) {
160
+ return {
161
+ kind: 'working',
162
+ activity: (0, activity_js_1.editingFiles)(Object.keys(item['changes']).map(stripFileUrl), cwd),
163
+ };
164
+ }
165
+ return null;
166
+ }
167
+ default:
168
+ if (/approval_request$/.test(type) || type === 'request_permissions') {
169
+ return { kind: 'waiting', activity: approvalText(payload, cwd) };
170
+ }
171
+ return null;
172
+ }
173
+ }
174
+ function parseResponseItem(payload, cwd) {
175
+ const type = s(payload['type']) ?? '';
176
+ if (type === 'custom_tool_call' || type === 'function_call') {
177
+ const name = s(payload['name']) ?? '';
178
+ const activity = describeCall(name, payload['input'] ?? payload['arguments'], cwd);
179
+ return activity ? { kind: 'working', activity } : null;
180
+ }
181
+ if (type === 'local_shell_call') {
182
+ const action = isObj(payload['action']) ? payload['action'] : {};
183
+ const short = (0, activity_js_1.shortCommand)(action['command']);
184
+ return { kind: 'working', activity: short ? `Running ${short}` : 'Running a command' };
185
+ }
186
+ if (type === 'web_search_call')
187
+ return { kind: 'working', activity: 'Searching the web' };
188
+ return null;
189
+ }
190
+ /** Parse one rollout line into a signal (or null when it carries nothing useful). */
191
+ function parseRolloutLine(line, cwd) {
192
+ const trimmed = line.trim();
193
+ if (!trimmed || trimmed[0] !== '{')
194
+ return null;
195
+ let rec;
196
+ try {
197
+ const parsed = JSON.parse(trimmed);
198
+ if (!isObj(parsed))
199
+ return null;
200
+ rec = parsed;
201
+ }
202
+ catch {
203
+ return null;
204
+ }
205
+ const type = s(rec['type']) ?? '';
206
+ const payload = isObj(rec['payload']) ? rec['payload'] : {};
207
+ switch (type) {
208
+ case 'session_meta': {
209
+ const meta = isObj(payload['meta']) ? payload['meta'] : payload; // older nesting
210
+ const sessionId = s(meta['id']) ?? s(meta['session_id']);
211
+ if (!sessionId)
212
+ return null;
213
+ const source = meta['source'];
214
+ const threadSource = s(meta['thread_source']);
215
+ const subagent = (isObj(source) && 'subagent' in source) ||
216
+ threadSource === 'subagent' ||
217
+ threadSource === 'guardian_review';
218
+ const exec = source === 'exec' || s(meta['originator']) === 'codex_exec';
219
+ return { kind: 'meta', sessionId, cwd: s(meta['cwd']), subagent, exec };
220
+ }
221
+ case 'turn_context': {
222
+ const c = s(payload['cwd']);
223
+ return c ? { kind: 'cwd', cwd: c } : null;
224
+ }
225
+ case 'event_msg':
226
+ return parseEventMsg(payload, cwd);
227
+ case 'response_item':
228
+ return parseResponseItem(payload, cwd);
229
+ case 'function_call':
230
+ case 'custom_tool_call':
231
+ case 'local_shell_call':
232
+ case 'web_search_call':
233
+ // 2025-era rollouts wrote response items unwrapped.
234
+ return parseResponseItem(rec, cwd);
235
+ case '': {
236
+ // 2025-era first line: bare `{ id, timestamp, instructions }` session header.
237
+ const id = s(rec['id']);
238
+ return id && s(rec['timestamp'])
239
+ ? { kind: 'meta', sessionId: id, subagent: false, exec: false }
240
+ : null;
241
+ }
242
+ default:
243
+ return null;
244
+ }
245
+ }
246
+ //# sourceMappingURL=rollout.js.map
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CODEX_HOOK_EVENTS = void 0;
4
+ exports.codexHooksPath = codexHooksPath;
5
+ exports.installCodexHooksInto = installCodexHooksInto;
6
+ exports.buildCodexHookCommand = buildCodexHookCommand;
7
+ exports.setupCodexHooks = setupCodexHooks;
8
+ exports.uninstallCodexHooks = uninstallCodexHooks;
9
+ const node_fs_1 = require("node:fs");
10
+ const node_path_1 = require("node:path");
11
+ const user_config_js_1 = require("../../core/user-config.js");
12
+ const hook_settings_js_1 = require("../agent-common/hook-settings.js");
13
+ const shim_js_1 = require("../agent-common/shim.js");
14
+ const runtime_js_1 = require("../agent-common/runtime.js");
15
+ const defaults_js_1 = require("./defaults.js");
16
+ /**
17
+ * Codex hook events we install (developers.openai.com/codex/hooks). PostCompact
18
+ * is omitted — it carries nothing displayable.
19
+ */
20
+ exports.CODEX_HOOK_EVENTS = [
21
+ 'SessionStart',
22
+ 'SessionEnd',
23
+ 'UserPromptSubmit',
24
+ 'PreToolUse',
25
+ 'PostToolUse',
26
+ 'PermissionRequest',
27
+ 'Stop',
28
+ 'Interrupt',
29
+ 'PreCompact',
30
+ 'SubagentStart',
31
+ 'SubagentStop',
32
+ ];
33
+ function codexHooksPath() {
34
+ return (0, node_path_1.join)((0, defaults_js_1.codexHome)(), 'hooks.json');
35
+ }
36
+ /** Install the nocville group into every Codex event. Mutates `file`. */
37
+ function installCodexHooksInto(file, command, opts = {}) {
38
+ return (0, hook_settings_js_1.installHookGroups)(file, command, exports.CODEX_HOOK_EVENTS, {
39
+ perEvent: Object.fromEntries(exports.CODEX_HOOK_EVENTS.map((event) => [
40
+ event,
41
+ event === 'SessionEnd' || event === 'Interrupt'
42
+ ? { timeout: 3 }
43
+ : { async: true, timeout: opts.timeout ?? 10 },
44
+ ])),
45
+ });
46
+ }
47
+ function buildCodexHookCommand(_cliPath) {
48
+ return (0, hook_settings_js_1.buildShimHookCommand)('codex');
49
+ }
50
+ function out(opts, msg) {
51
+ if (!opts.quiet)
52
+ console.log(msg);
53
+ }
54
+ /**
55
+ * Install Nocville hooks into `~/.codex/hooks.json` (same matcher-group JSON
56
+ * format as Claude Code). Merges with existing hooks, idempotent, keeps a
57
+ * one-time `.nocville-backup`. Codex requires new hooks to be reviewed and
58
+ * trusted once via `/hooks` before they run — we print that instruction.
59
+ */
60
+ function setupCodexHooks(opts = {}) {
61
+ const hooksPath = opts.hooksPath ?? codexHooksPath();
62
+ const dir = (0, node_path_1.join)(hooksPath, '..');
63
+ if (!(0, node_fs_1.existsSync)(dir)) {
64
+ console.error(`${dir} does not exist — is Codex installed? Skipping Codex setup.`);
65
+ return false;
66
+ }
67
+ const file = (0, hook_settings_js_1.readJsonFile)(hooksPath);
68
+ if (file === null) {
69
+ console.error(`Could not parse ${hooksPath}; fix it (or move it aside) and re-run setup.`);
70
+ return false;
71
+ }
72
+ const creds = (0, user_config_js_1.persistCredentials)(opts);
73
+ const resolved = (0, hook_settings_js_1.resolveCliPath)(opts.cliPath);
74
+ const cliPath = (0, runtime_js_1.ensureStableCliPath)(resolved);
75
+ (0, shim_js_1.installHookShim)((0, hook_settings_js_1.stableNodePath)(), cliPath);
76
+ const { installed } = installCodexHooksInto(file, buildCodexHookCommand(cliPath), {
77
+ timeout: defaults_js_1.CODEX_DEFAULTS.hookTimeoutSeconds,
78
+ });
79
+ (0, hook_settings_js_1.writeJsonFile)(hooksPath, file);
80
+ out(opts, `✓ Codex: installed Nocville hooks for ${installed} events in ${hooksPath}`);
81
+ out(opts, ` Hook runs: ${process.execPath} ${cliPath}`);
82
+ out(opts, ` API: ${creds.apiUrl ?? 'https://nocville.com'} key: ${(0, user_config_js_1.maskKey)(creds.apiKey)}`);
83
+ if (!creds.apiKey) {
84
+ out(opts, ' ⚠ No API key saved yet — run: nocville-npc init --api-key=<your team key>');
85
+ }
86
+ out(opts, ' ➜ One-time step: start Codex and run /hooks to review and trust the Nocville');
87
+ out(opts, ' hooks (Codex skips new hooks until trusted).');
88
+ return true;
89
+ }
90
+ /** Remove all Nocville hooks from `~/.codex/hooks.json`. */
91
+ function uninstallCodexHooks(opts = {}) {
92
+ const hooksPath = opts.hooksPath ?? codexHooksPath();
93
+ const file = (0, hook_settings_js_1.readJsonFile)(hooksPath);
94
+ if (!file || !(0, node_fs_1.existsSync)(hooksPath)) {
95
+ out(opts, 'Codex: no hooks.json — nothing to remove.');
96
+ return 0;
97
+ }
98
+ const removed = (0, hook_settings_js_1.removeHookGroups)(file);
99
+ if (removed > 0)
100
+ (0, hook_settings_js_1.writeJsonFile)(hooksPath, file);
101
+ out(opts, `✓ Codex: removed ${removed} Nocville hook(s) from ${hooksPath}`);
102
+ return removed;
103
+ }
104
+ //# sourceMappingURL=setup.js.map