oh-my-copilot 5.6.2 → 5.7.0

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 (127) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +1 -0
  4. package/bridge/__pycache__/gyoshu_bridge.cpython-312.pyc +0 -0
  5. package/bridge/claude-md-coordinator.cjs +2 -2
  6. package/bridge/cli.cjs +78578 -75769
  7. package/bridge/mcp-server.cjs +36510 -32259
  8. package/bridge/runtime-cli.cjs +95 -34
  9. package/bridge/team-mcp.cjs +95 -34
  10. package/bridge/team.js +131 -70
  11. package/dist/__tests__/run-cjs-fail-closed-timeout.test.d.ts +2 -0
  12. package/dist/__tests__/run-cjs-fail-closed-timeout.test.d.ts.map +1 -0
  13. package/dist/__tests__/run-cjs-fail-closed-timeout.test.js +68 -0
  14. package/dist/__tests__/run-cjs-fail-closed-timeout.test.js.map +1 -0
  15. package/dist/__tests__/session-end-process-exit.test.js +70 -2
  16. package/dist/__tests__/session-end-process-exit.test.js.map +1 -1
  17. package/dist/cli/commands/__tests__/smoke-tier2.test.d.ts +2 -0
  18. package/dist/cli/commands/__tests__/smoke-tier2.test.d.ts.map +1 -0
  19. package/dist/cli/commands/__tests__/smoke-tier2.test.js +72 -0
  20. package/dist/cli/commands/__tests__/smoke-tier2.test.js.map +1 -0
  21. package/dist/cli/commands/smoke.d.ts +36 -0
  22. package/dist/cli/commands/smoke.d.ts.map +1 -0
  23. package/dist/cli/commands/smoke.js +169 -0
  24. package/dist/cli/commands/smoke.js.map +1 -0
  25. package/dist/cli/index.d.ts.map +1 -1
  26. package/dist/cli/index.js +39 -0
  27. package/dist/cli/index.js.map +1 -1
  28. package/dist/constants/names.d.ts +1 -0
  29. package/dist/constants/names.d.ts.map +1 -1
  30. package/dist/constants/names.js +1 -0
  31. package/dist/constants/names.js.map +1 -1
  32. package/dist/hooks/session-end/index.d.ts +2 -3
  33. package/dist/hooks/session-end/index.d.ts.map +1 -1
  34. package/dist/hooks/session-end/index.js +3 -10
  35. package/dist/hooks/session-end/index.js.map +1 -1
  36. package/dist/hooks/session-end/wiki-foreground-bootstrap.d.ts +17 -0
  37. package/dist/hooks/session-end/wiki-foreground-bootstrap.d.ts.map +1 -0
  38. package/dist/hooks/session-end/wiki-foreground-bootstrap.js +20 -0
  39. package/dist/hooks/session-end/wiki-foreground-bootstrap.js.map +1 -0
  40. package/dist/lib/__tests__/atomic-write.test.js +32 -1
  41. package/dist/lib/__tests__/atomic-write.test.js.map +1 -1
  42. package/dist/lib/__tests__/mode-state-lock.test.js +121 -12
  43. package/dist/lib/__tests__/mode-state-lock.test.js.map +1 -1
  44. package/dist/lib/atomic-write.d.ts +13 -3
  45. package/dist/lib/atomic-write.d.ts.map +1 -1
  46. package/dist/lib/atomic-write.js +29 -15
  47. package/dist/lib/atomic-write.js.map +1 -1
  48. package/dist/lib/mode-state-io.d.ts +2 -2
  49. package/dist/lib/mode-state-io.d.ts.map +1 -1
  50. package/dist/lib/mode-state-io.js +16 -10
  51. package/dist/lib/mode-state-io.js.map +1 -1
  52. package/dist/mcp/__tests__/host-smoke-tool.test.d.ts +2 -0
  53. package/dist/mcp/__tests__/host-smoke-tool.test.d.ts.map +1 -0
  54. package/dist/mcp/__tests__/host-smoke-tool.test.js +174 -0
  55. package/dist/mcp/__tests__/host-smoke-tool.test.js.map +1 -0
  56. package/dist/mcp/disable-tools.d.ts.map +1 -1
  57. package/dist/mcp/disable-tools.js +1 -0
  58. package/dist/mcp/disable-tools.js.map +1 -1
  59. package/dist/mcp/tool-registry.d.ts.map +1 -1
  60. package/dist/mcp/tool-registry.js +2 -0
  61. package/dist/mcp/tool-registry.js.map +1 -1
  62. package/dist/smoke/__tests__/copilot-sdk-driver.test.d.ts +2 -0
  63. package/dist/smoke/__tests__/copilot-sdk-driver.test.d.ts.map +1 -0
  64. package/dist/smoke/__tests__/copilot-sdk-driver.test.js +561 -0
  65. package/dist/smoke/__tests__/copilot-sdk-driver.test.js.map +1 -0
  66. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.d.ts +2 -0
  67. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.d.ts.map +1 -0
  68. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.js +311 -0
  69. package/dist/smoke/__tests__/copilot-sdk-scenarios.test.js.map +1 -0
  70. package/dist/smoke/__tests__/copilot-session-eval.test.d.ts +2 -0
  71. package/dist/smoke/__tests__/copilot-session-eval.test.d.ts.map +1 -0
  72. package/dist/smoke/__tests__/copilot-session-eval.test.js +264 -0
  73. package/dist/smoke/__tests__/copilot-session-eval.test.js.map +1 -0
  74. package/dist/smoke/__tests__/copilot-smoke.test.d.ts +2 -0
  75. package/dist/smoke/__tests__/copilot-smoke.test.d.ts.map +1 -0
  76. package/dist/smoke/__tests__/copilot-smoke.test.js +482 -0
  77. package/dist/smoke/__tests__/copilot-smoke.test.js.map +1 -0
  78. package/dist/smoke/copilot-binary.d.ts +21 -0
  79. package/dist/smoke/copilot-binary.d.ts.map +1 -0
  80. package/dist/smoke/copilot-binary.js +46 -0
  81. package/dist/smoke/copilot-binary.js.map +1 -0
  82. package/dist/smoke/copilot-sdk-driver.d.ts +186 -0
  83. package/dist/smoke/copilot-sdk-driver.d.ts.map +1 -0
  84. package/dist/smoke/copilot-sdk-driver.js +622 -0
  85. package/dist/smoke/copilot-sdk-driver.js.map +1 -0
  86. package/dist/smoke/copilot-sdk-scenarios.d.ts +159 -0
  87. package/dist/smoke/copilot-sdk-scenarios.d.ts.map +1 -0
  88. package/dist/smoke/copilot-sdk-scenarios.js +510 -0
  89. package/dist/smoke/copilot-sdk-scenarios.js.map +1 -0
  90. package/dist/smoke/copilot-session-eval.d.ts +90 -0
  91. package/dist/smoke/copilot-session-eval.d.ts.map +1 -0
  92. package/dist/smoke/copilot-session-eval.js +323 -0
  93. package/dist/smoke/copilot-session-eval.js.map +1 -0
  94. package/dist/smoke/copilot-smoke.d.ts +228 -0
  95. package/dist/smoke/copilot-smoke.d.ts.map +1 -0
  96. package/dist/smoke/copilot-smoke.js +818 -0
  97. package/dist/smoke/copilot-smoke.js.map +1 -0
  98. package/dist/smoke/process-utils.d.ts +47 -0
  99. package/dist/smoke/process-utils.d.ts.map +1 -0
  100. package/dist/smoke/process-utils.js +99 -0
  101. package/dist/smoke/process-utils.js.map +1 -0
  102. package/dist/team/__tests__/tmux-session.pane-env.test.d.ts +2 -0
  103. package/dist/team/__tests__/tmux-session.pane-env.test.d.ts.map +1 -0
  104. package/dist/team/__tests__/tmux-session.pane-env.test.js +52 -0
  105. package/dist/team/__tests__/tmux-session.pane-env.test.js.map +1 -0
  106. package/dist/team/tmux-session.d.ts +7 -0
  107. package/dist/team/tmux-session.d.ts.map +1 -1
  108. package/dist/team/tmux-session.js +80 -18
  109. package/dist/team/tmux-session.js.map +1 -1
  110. package/dist/tools/host-smoke-tool.d.ts +34 -0
  111. package/dist/tools/host-smoke-tool.d.ts.map +1 -0
  112. package/dist/tools/host-smoke-tool.js +133 -0
  113. package/dist/tools/host-smoke-tool.js.map +1 -0
  114. package/docs/CLAUDE.md +1 -1
  115. package/docs/DEVELOPERS.md +101 -0
  116. package/docs/HOOKS.md +1 -1
  117. package/docs/MIGRATION.md +71 -0
  118. package/docs/REFERENCE.md +42 -1
  119. package/docs/TOOLS.md +32 -1
  120. package/package.json +11 -2
  121. package/plugin.json +1 -1
  122. package/scripts/dev/repro-state-lock.mjs +1 -1
  123. package/scripts/lib/atomic-write.mjs +4 -2
  124. package/scripts/lib/state-lock.mjs +21 -12
  125. package/scripts/run.cjs +13 -3
  126. package/scripts/wiki-session-end.mjs +2 -1
  127. package/templates/hooks/lib/atomic-write.mjs +4 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-session-eval.d.ts","sourceRoot":"","sources":["../../src/smoke/copilot-session-eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,323 @@
1
+ /**
2
+ * Pure evaluators for the artifacts of a Tier 1 `omg smoke copilot` session:
3
+ * stdout JSONL, `<COPILOT_HOME>/session-state/<id>/events.jsonl`, the debug
4
+ * process log, and the project's `.omg/` state. Kept free of process spawning
5
+ * so the unit tests can run them against captured fixtures.
6
+ */
7
+ import { existsSync, readdirSync, statSync } from 'fs';
8
+ import { join, relative } from 'path';
9
+ export const EVIDENCE_MAX = 400;
10
+ export function excerpt(text, max = EVIDENCE_MAX) {
11
+ if (!text)
12
+ return '';
13
+ const flat = text.replace(/\r/g, '').trim();
14
+ return flat.length <= max ? flat : `${flat.slice(0, max - 3)}...`;
15
+ }
16
+ /** Parse JSON Lines defensively: non-JSON lines are counted, never thrown. */
17
+ export function parseJsonl(text) {
18
+ const events = [];
19
+ let bad = 0;
20
+ let badSample;
21
+ for (const line of text.split(/\r?\n/)) {
22
+ const trimmed = line.trim();
23
+ if (!trimmed)
24
+ continue;
25
+ try {
26
+ const parsed = JSON.parse(trimmed);
27
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
28
+ events.push(parsed);
29
+ else {
30
+ bad++;
31
+ badSample ??= trimmed;
32
+ }
33
+ }
34
+ catch {
35
+ bad++;
36
+ badSample ??= trimmed;
37
+ }
38
+ }
39
+ return { events, bad, badSample };
40
+ }
41
+ function str(value) {
42
+ return typeof value === 'string' ? value : '';
43
+ }
44
+ /** Concatenated assistant output (final messages and deltas). */
45
+ export function assistantText(events) {
46
+ return events
47
+ .filter((e) => typeof e.type === 'string' && e.type.startsWith('assistant.message'))
48
+ .map((e) => str(e.data?.content) || str(e.data?.deltaContent) || str(e.data?.text))
49
+ .join('');
50
+ }
51
+ export const SMOKE_TOKEN = 'SMOKE_OK';
52
+ export function evaluateSessionExit(input) {
53
+ const { events } = parseJsonl(input.stdout);
54
+ // Only assistant output counts: the prompt itself (echoed as user.message) contains the token.
55
+ const answer = events.length > 0 ? assistantText(events) : input.stdout;
56
+ const source = events.length > 0 ? `${events.length} JSONL events` : 'raw stdout';
57
+ const sawToken = answer.includes(SMOKE_TOKEN);
58
+ if (input.timedOut) {
59
+ return { id: 'session.exit', ok: false, detail: `timed out after ${input.timeoutMs} ms (process tree killed)`, evidence: excerpt(input.stderr || input.stdout) };
60
+ }
61
+ if (input.error) {
62
+ return { id: 'session.exit', ok: false, detail: `spawn failed: ${input.error}` };
63
+ }
64
+ const ok = input.exitCode === 0 && sawToken;
65
+ const modelHint = /from --model flag is not available/.test(input.stderr) ? '; the CLI rejected --model, omit it to let the CLI auto-pick' : '';
66
+ return {
67
+ id: 'session.exit',
68
+ ok,
69
+ detail: ok
70
+ ? `exit 0, assistant replied ${SMOKE_TOKEN} (${source})`
71
+ : `exit ${input.exitCode}, ${sawToken ? 'token present' : `${SMOKE_TOKEN} missing from assistant output`} (${source})${modelHint}`,
72
+ ...(ok ? {} : { evidence: excerpt(input.stderr.trim() || answer || input.stdout.slice(-EVIDENCE_MAX)) }),
73
+ };
74
+ }
75
+ export function evaluateEventsLog(eventsPath, text) {
76
+ if (text === null) {
77
+ return { check: { id: 'session.events', ok: false, detail: `missing ${eventsPath}` }, events: [] };
78
+ }
79
+ const { events, bad, badSample } = parseJsonl(text);
80
+ const ok = events.length > 0 && bad === 0;
81
+ return {
82
+ check: {
83
+ id: 'session.events',
84
+ ok,
85
+ detail: `${events.length} events parsed, ${bad} unparseable line(s)`,
86
+ ...(ok ? {} : { evidence: excerpt(badSample ?? text) }),
87
+ },
88
+ events,
89
+ };
90
+ }
91
+ /** Hook types the default (tool-free) prompt must fire. */
92
+ export const REQUIRED_HOOK_TYPES = ['sessionStart', 'userPromptSubmitted', 'agentStop', 'sessionEnd'];
93
+ /** Hook types that only fire when the model used a tool. */
94
+ export const TOOL_HOOK_TYPES = ['preToolUse', 'postToolUse'];
95
+ /**
96
+ * Pair `hook.start` with `hook.end`. The end event's `hookType` is used when
97
+ * present; otherwise it is matched through a shared invocation id or the
98
+ * start event's id (parentId).
99
+ */
100
+ export function collectHookRuns(events) {
101
+ const runs = [];
102
+ const byKey = new Map();
103
+ const keysOf = (e) => {
104
+ const d = e.data ?? {};
105
+ return [str(d.hookInvocationId), str(d.invocationId), str(d.hookId)].filter(Boolean);
106
+ };
107
+ for (const e of events) {
108
+ if (e.type === 'hook.start') {
109
+ const run = { hookType: str(e.data?.hookType), ended: false, success: null };
110
+ runs.push(run);
111
+ for (const key of keysOf(e))
112
+ byKey.set(key, run);
113
+ if (e.id)
114
+ byKey.set(`id:${e.id}`, run);
115
+ }
116
+ else if (e.type === 'hook.end') {
117
+ const d = e.data ?? {};
118
+ let run = keysOf(e).map((k) => byKey.get(k)).find(Boolean)
119
+ ?? (e.parentId ? byKey.get(`id:${e.parentId}`) : undefined);
120
+ const hookType = str(d.hookType) || run?.hookType || '';
121
+ if (!run || (hookType && run.hookType && run.hookType !== hookType) || run.ended) {
122
+ run = runs.find((r) => !r.ended && r.hookType === hookType);
123
+ }
124
+ if (!run) {
125
+ run = { hookType, ended: false, success: null };
126
+ runs.push(run);
127
+ }
128
+ run.ended = true;
129
+ run.success = typeof d.success === 'boolean' ? d.success : (d.error ? false : null);
130
+ const err = d.error;
131
+ if (err)
132
+ run.error = typeof err === 'string' ? err : JSON.stringify(err);
133
+ }
134
+ }
135
+ return runs;
136
+ }
137
+ export function evaluateHooks(events) {
138
+ const runs = collectHookRuns(events);
139
+ const toolUsed = events.some((e) => e.type === 'tool.execution_start');
140
+ const checks = [];
141
+ const check = (hookType, optional) => {
142
+ const mine = runs.filter((r) => r.hookType === hookType);
143
+ const id = `hooks.${hookType}`;
144
+ if (mine.length === 0) {
145
+ if (optional && !toolUsed)
146
+ return { id, ok: true, detail: 'n/a (no tool use)' };
147
+ return { id, ok: false, detail: `no hook.start/hook.end with hookType ${hookType}` };
148
+ }
149
+ const ended = mine.filter((r) => r.ended);
150
+ // Only an explicit success:true passes; a missing/null flag is not evidence of success.
151
+ const failed = ended.filter((r) => r.success !== true);
152
+ const ok = ended.length > 0 && failed.length === 0;
153
+ return {
154
+ id,
155
+ ok,
156
+ detail: `${mine.length} start(s), ${ended.length} end(s), ${failed.length} without success:true`,
157
+ ...(ok ? {} : {
158
+ evidence: excerpt(failed.map((r) => r.error ?? `success=${String(r.success)}`).join(' | ') || 'hook.end missing'),
159
+ }),
160
+ };
161
+ };
162
+ for (const t of REQUIRED_HOOK_TYPES)
163
+ checks.push(check(t, false));
164
+ for (const t of TOOL_HOOK_TYPES)
165
+ checks.push(check(t, true));
166
+ return checks;
167
+ }
168
+ /**
169
+ * `[omg-hook]` stderr lines from scripts/lib/copilot-hook-adapter.cjs that are
170
+ * informational, not failures. Every other `[omg-hook]` line (internal error /
171
+ * failing open, adapter error, hook target is not a file) fails the check.
172
+ */
173
+ export const BENIGN_ADAPTER_NOTES = [/continue:false overrides decision:block/, /dropped hookSpecificOutput\.updatedInput/];
174
+ /**
175
+ * The adapter fails open by default (non-zero exit -> 0 plus an `[omg-hook]`
176
+ * stderr line), which Copilot records as `hook.end success:true`. The smoke
177
+ * runs with OMC_HOOK_FAIL_CLOSED=1, and this check catches what still slips
178
+ * through by scanning every captured stream for adapter error lines.
179
+ */
180
+ export function evaluateAdapterErrors(sources) {
181
+ const id = 'hooks.adapter_errors';
182
+ const hits = [];
183
+ const scanned = [];
184
+ for (const { name, text } of sources) {
185
+ if (!text)
186
+ continue;
187
+ scanned.push(name);
188
+ for (const line of text.split(/\r?\n/)) {
189
+ if (!line.includes('[omg-hook]'))
190
+ continue;
191
+ if (BENIGN_ADAPTER_NOTES.some((re) => re.test(line)))
192
+ continue;
193
+ hits.push(`${name}: ${line.trim()}`);
194
+ }
195
+ }
196
+ if (hits.length === 0) {
197
+ return { id, ok: true, detail: `no [omg-hook] error lines in ${scanned.join(', ') || 'any captured stream'}` };
198
+ }
199
+ return { id, ok: false, detail: `${hits.length} [omg-hook] error line(s): a hook failed`, evidence: excerpt(hits.join('\n')) };
200
+ }
201
+ const PLUGIN_NAME = 'oh-my-copilot';
202
+ /** Plugin names from a `Plugins loaded: ["a","b"]` debug line (exact names, not substrings). */
203
+ export function parsePluginsLoaded(line) {
204
+ const rest = line.slice(line.indexOf('Plugins loaded:') + 'Plugins loaded:'.length).trim();
205
+ try {
206
+ const parsed = JSON.parse(rest);
207
+ if (Array.isArray(parsed))
208
+ return parsed.filter((n) => typeof n === 'string');
209
+ }
210
+ catch { /* not a JSON array */ }
211
+ return [...rest.matchAll(/"([^"]+)"/g)].map((m) => m[1]);
212
+ }
213
+ export function evaluatePluginsLoaded(logText) {
214
+ const id = 'plugins.loaded';
215
+ if (logText === null)
216
+ return { id, ok: false, detail: 'no debug log found under <home>/logs' };
217
+ const loadedLine = logText.split(/\r?\n/).find((l) => l.includes('Plugins loaded:'));
218
+ const activationLine = logText.split(/\r?\n/).find((l) => /Plugin activation \[agents\]/.test(l));
219
+ const listed = !!loadedLine && parsePluginsLoaded(loadedLine).includes(PLUGIN_NAME);
220
+ const activated = !!activationLine && /loaded=([1-9]\d*)/.test(activationLine);
221
+ const ok = listed && activated;
222
+ return {
223
+ id,
224
+ ok,
225
+ detail: ok
226
+ ? `Plugins loaded lists ${PLUGIN_NAME}; agents activation loaded>=1`
227
+ : `${listed ? '' : `"Plugins loaded:" without ${PLUGIN_NAME}; `}${activated ? '' : 'no "Plugin activation [agents]" with loaded>=1'}`.trim(),
228
+ evidence: excerpt([loadedLine, activationLine].filter(Boolean).join('\n')) || undefined,
229
+ };
230
+ }
231
+ export const MCP_STDERR_TAG = 'OMC Tools MCP Server running on stdio';
232
+ export function evaluateMcpLoaded(events, logText, serverNames) {
233
+ const id = 'mcp.server_loaded';
234
+ const loaded = events.filter((e) => e.type === 'session.mcp_servers_loaded');
235
+ const mentionsOurs = (value) => {
236
+ const json = JSON.stringify(value ?? '');
237
+ return serverNames.some((n) => json.includes(`"${n}"`));
238
+ };
239
+ const ours = loaded.find((e) => mentionsOurs(e.data));
240
+ if (ours) {
241
+ return { id, ok: true, detail: `session.mcp_servers_loaded lists ${serverNames.join(', ')} (events)`, evidence: excerpt(JSON.stringify(ours.data)) };
242
+ }
243
+ const statusChange = events.find((e) => e.type === 'session.mcp_server_status_changed'
244
+ && serverNames.includes(str(e.data?.serverName)) && str(e.data?.status) === 'connected');
245
+ if (statusChange) {
246
+ return { id, ok: true, detail: `session.mcp_server_status_changed ${str(statusChange.data?.serverName)}=connected (events)`, evidence: excerpt(JSON.stringify(statusChange.data)) };
247
+ }
248
+ const tagLine = logText?.split(/\r?\n/).find((l) => l.includes(MCP_STDERR_TAG)
249
+ && serverNames.some((n) => l.includes(`"server_name":"${n}"`) || l.includes(`server_name: ${n}`) || l.includes(`"serverName":"${n}"`)))
250
+ ?? logText?.split(/\r?\n/).find((l) => l.includes(MCP_STDERR_TAG));
251
+ if (tagLine) {
252
+ return { id, ok: true, detail: 'debug log shows the plugin MCP server stderr tag', evidence: excerpt(tagLine) };
253
+ }
254
+ return {
255
+ id,
256
+ ok: false,
257
+ detail: `no session.mcp_servers_loaded/status event naming ${serverNames.join(', ')} and no "${MCP_STDERR_TAG}" in the debug log`,
258
+ evidence: excerpt(loaded.map((e) => JSON.stringify(e.data)).join('\n')) || undefined,
259
+ };
260
+ }
261
+ export const SESSION_STARTED_MARKER = 'session-started.json';
262
+ function walkFiles(root, limit = 500) {
263
+ const out = [];
264
+ const stack = [root];
265
+ while (stack.length && out.length < limit) {
266
+ const dir = stack.pop();
267
+ let entries;
268
+ try {
269
+ entries = readdirSync(dir);
270
+ }
271
+ catch {
272
+ continue;
273
+ }
274
+ for (const name of entries) {
275
+ const full = join(dir, name);
276
+ try {
277
+ if (statSync(full).isDirectory())
278
+ stack.push(full);
279
+ else
280
+ out.push(full);
281
+ }
282
+ catch { /* raced */ }
283
+ }
284
+ }
285
+ return out;
286
+ }
287
+ /**
288
+ * Our SessionStart hook (scripts/session-start.mjs) writes
289
+ * `.omg/state/sessions/<id>/session-started.json`; other hooks add more files
290
+ * under `.omg/`. Pass when the marker exists, else when anything was written.
291
+ */
292
+ export function evaluateStateWritten(projectDir) {
293
+ const id = 'state.written';
294
+ const omgRoot = join(projectDir, '.omg');
295
+ if (!existsSync(omgRoot))
296
+ return { id, ok: false, detail: `${omgRoot} was not created by the hooks` };
297
+ const files = walkFiles(omgRoot).map((f) => relative(projectDir, f).replace(/\\/g, '/'));
298
+ const marker = files.find((f) => f.endsWith(`/${SESSION_STARTED_MARKER}`) && f.includes('state/sessions/'));
299
+ if (marker)
300
+ return { id, ok: true, detail: `SessionStart wrote ${marker}`, evidence: excerpt(files.join('\n')) };
301
+ return {
302
+ id,
303
+ ok: false,
304
+ detail: files.length ? `.omg/ has ${files.length} file(s) but no state/sessions/*/${SESSION_STARTED_MARKER}` : '.omg/ exists but is empty',
305
+ evidence: excerpt(files.join('\n')) || undefined,
306
+ };
307
+ }
308
+ export function evaluateSubagent(events, agentName) {
309
+ const id = 'subagent.selected';
310
+ const named = (type) => events.find((e) => e.type === type && str(e.data?.agentName) === agentName);
311
+ // 1.0.91 emits subagent.started before subagent.selected; prefer the contract's event.
312
+ const hit = named('subagent.selected') ?? named('subagent.started');
313
+ if (hit)
314
+ return { id, ok: true, detail: `${hit.type} ${agentName}`, evidence: excerpt(JSON.stringify(hit.data)) };
315
+ const any = events.filter((e) => typeof e.type === 'string' && e.type.startsWith('subagent.'));
316
+ return {
317
+ id,
318
+ ok: false,
319
+ detail: `no subagent.selected/started for ${agentName}`,
320
+ evidence: excerpt(any.map((e) => `${e.type} ${JSON.stringify(e.data)}`).join('\n')) || undefined,
321
+ };
322
+ }
323
+ //# sourceMappingURL=copilot-session-eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-session-eval.js","sourceRoot":"","sources":["../../src/smoke/copilot-session-eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * `omg smoke copilot` — load-check the oh-my-copilot plugin inside the real
3
+ * GitHub Copilot CLI.
4
+ *
5
+ * Tier 0 makes no model call: manifest/version, generated hooks/agents drift,
6
+ * `plugin list`/`skill list` against `--plugin-dir`, and the standalone MCP
7
+ * server's tools/list. Tier 1 adds one cheap non-interactive session in a
8
+ * throwaway COPILOT_HOME and asserts on its persisted events, debug log and
9
+ * the `.omg/` state our hooks write. Tier 2 replaces that session with
10
+ * `@github/copilot-sdk` static checks and scripted scenarios
11
+ * (src/smoke/copilot-sdk-driver.ts).
12
+ */
13
+ import { type BinaryResolverDeps } from './copilot-binary.js';
14
+ import { type SmokeCheck } from './copilot-session-eval.js';
15
+ import { type SpawnFn, type SpawnSyncFn } from './process-utils.js';
16
+ import { type LoadSdkFn } from './copilot-sdk-driver.js';
17
+ import { type Scenario, type ScenarioCost } from './copilot-sdk-scenarios.js';
18
+ export type { SmokeCheck } from './copilot-session-eval.js';
19
+ export type { Scenario } from './copilot-sdk-scenarios.js';
20
+ export { ALL_SCENARIOS, DEFAULT_SCENARIOS } from './copilot-sdk-scenarios.js';
21
+ export type SmokeTier = 0 | 1 | 2;
22
+ export interface SmokeOptions {
23
+ /** Default: OMC_PLUGIN_ROOT, else the package root of the running omg. */
24
+ pluginRoot: string;
25
+ /**
26
+ * 0 = load check (no model call); 1 = tier 0 + one live session;
27
+ * 2 = tier 0 + @github/copilot-sdk static checks + {@link SmokeOptions.scenarios}.
28
+ */
29
+ tier: SmokeTier;
30
+ copilotBin?: string;
31
+ /**
32
+ * Tier 1 model. Default {@link DEFAULT_SMOKE_MODEL}. Tier 2: the session
33
+ * model (default: a cheap explicit model from models.list, else auto).
34
+ */
35
+ model?: string;
36
+ /**
37
+ * Tier 1 `--max-ai-credits` (CLI minimum is {@link MIN_MAX_CREDITS}).
38
+ * Tier 2: a cap for the whole run. A scenario whose `assistant.usage`
39
+ * credits pass what is left is aborted, later scenarios are skipped, and the
40
+ * runtime also gets `--max-ai-credits` (raised to the CLI minimum).
41
+ */
42
+ maxCredits?: number;
43
+ /**
44
+ * Per subprocess at tier 0 (default 60 s); the tier 1 session (default 180 s);
45
+ * each tier 2 scenario (default 120 s, then abort). Tier 0 steps of a tier 1/2
46
+ * run keep 60 s. The mcp.list_tools check is fixed at 10 s.
47
+ */
48
+ timeoutMs?: number;
49
+ /** Keep the throwaway COPILOT_HOME and project dir for debugging. */
50
+ keepHome?: boolean;
51
+ /** Tier 1 prompt override. */
52
+ prompt?: string;
53
+ /** Tier 1: use the delegation prompt and add the `subagent.selected` check. */
54
+ delegate?: boolean;
55
+ /** Tier 2 scenarios (default {@link DEFAULT_SCENARIOS}); [] = SDK static checks only, zero model calls. */
56
+ scenarios?: Scenario[];
57
+ env?: NodeJS.ProcessEnv;
58
+ /** Test seams; defaults are the real implementations. */
59
+ deps?: SmokeDeps;
60
+ }
61
+ export interface SmokeDeps extends BinaryResolverDeps {
62
+ spawn?: SpawnFn;
63
+ spawnSync?: SpawnSyncFn;
64
+ /** Expected standalone MCP tool count (default: tool-registry `allTools.length`). */
65
+ loadExpectedToolCount?: () => Promise<number>;
66
+ randomUUID?: () => string;
67
+ /** Real Copilot config dir to copy the login identity from (default getCopilotConfigDir()). */
68
+ userConfigDir?: string;
69
+ /** Tier 2: resolve @github/copilot-sdk (default {@link loadCopilotSdk}); null = not installed. */
70
+ loadSdk?: LoadSdkFn;
71
+ }
72
+ export interface SmokeReport {
73
+ ok: boolean;
74
+ tier: SmokeTier;
75
+ pluginRoot: string;
76
+ pluginVersion: string | null;
77
+ copilot: {
78
+ bin: string | null;
79
+ version: string | null;
80
+ };
81
+ checks: SmokeCheck[];
82
+ artifacts: SmokeArtifacts;
83
+ durationMs: number;
84
+ skipped?: string;
85
+ /** Tier 2: SDK package and runtime it drove; `model` is the scenario model or `auto`. */
86
+ sdk?: {
87
+ version: string | null;
88
+ runtimeVersion: string | null;
89
+ protocolVersion: number | null;
90
+ model?: string;
91
+ };
92
+ /** Tier 2: summed over the scenarios (AI credits = nano-AIU / 1e9). */
93
+ cost?: ScenarioCost;
94
+ }
95
+ /**
96
+ * Paths kept with keepHome (else deleted and omitted). `listHome` is the tier 0
97
+ * COPILOT_HOME used for `plugin list`/`skill list`; `copilotHome` is the tier 1
98
+ * session's COPILOT_HOME (its parent also holds the temp project).
99
+ */
100
+ export interface SmokeArtifacts {
101
+ listHome?: string;
102
+ copilotHome?: string;
103
+ eventsLog?: string;
104
+ debugLog?: string;
105
+ stdout?: string;
106
+ /** Tier 2: per-scenario SDK event stream (JSONL) under copilotHome. */
107
+ events?: Partial<Record<Scenario, string>>;
108
+ }
109
+ /**
110
+ * No default model id: on Copilot CLI 1.0.91 every explicit `--model` tried
111
+ * (gpt-5-mini, gpt-6-luna, claude-sonnet-5) failed with `Model "<id>" from
112
+ * --model flag is not available` before any model call, while omitting the
113
+ * flag lets the CLI auto-pick (it chose mai-code-1.1-flash, a low-price flash
114
+ * model). Cost stays bounded by --max-ai-credits. Pass --model to pin one.
115
+ */
116
+ export declare const DEFAULT_SMOKE_MODEL: string | undefined;
117
+ export declare const DEFAULT_MAX_CREDITS = 30;
118
+ /** Copilot CLI rejects `--max-ai-credits` below this. */
119
+ export declare const MIN_MAX_CREDITS = 30;
120
+ export declare const DEFAULT_TIER0_TIMEOUT_MS = 60000;
121
+ export declare const DEFAULT_TIER1_TIMEOUT_MS = 180000;
122
+ export declare const MCP_LIST_TIMEOUT_MS = 10000;
123
+ export declare const PLUGIN_NAME = "oh-my-copilot";
124
+ export declare const DELEGATE_AGENT = "oh-my-copilot:architect";
125
+ export declare const DEFAULT_SMOKE_PROMPT = "Reply with exactly: SMOKE_OK. Do not use tools.";
126
+ export declare const DELEGATE_SMOKE_PROMPT: string;
127
+ /**
128
+ * Tier 1 session sandboxing (spellings verified against `copilot --help` and
129
+ * `copilot help permissions`, CLI 1.0.91; deny rules beat --allow-all-tools):
130
+ * - never let the model call our own `host_smoke` tool (server `t`) recursively;
131
+ * - no built-in MCP servers (github-mcp-server, githubiq) in the smoke;
132
+ * - the default prompt forbids tools, so also deny shell and file writes.
133
+ * `--delegate` keeps them, because the subagent hand-off is a tool call.
134
+ */
135
+ export declare function sessionSandboxFlags(delegate: boolean): string[];
136
+ /**
137
+ * Env policy for every copilot child the smoke spawns (the caller's env minus
138
+ * what could redirect, disable, or re-host our hooks; precedent:
139
+ * scripts/verify-graph-contained-fs.mjs).
140
+ *
141
+ * Stripped:
142
+ * - every `OMC_*` var and `DISABLE_OMC` (state dir, plugin root, skip/disable
143
+ * switches, debug toggles), then only {@link SMOKE_SET_ENV} is re-added;
144
+ * - Claude Code host markers: `CLAUDECODE`, `CLAUDE_SESSION_ID`,
145
+ * `CLAUDE_PLUGIN_ROOT`, and every `CLAUDE_CODE_*` (incl. CLAUDE_CODE_ENTRYPOINT);
146
+ * - `NODE_OPTIONS` (preloads would run inside our node hooks);
147
+ * - `COPILOT_HOME`, `COPILOT_OFFLINE`, `COPILOT_MODEL` (only `--model` picks the
148
+ * model), every `COPILOT_PROVIDER_*` (BYO provider routing);
149
+ * - tier 1 with a copied login identity: `GH_TOKEN`, `GITHUB_TOKEN` (see
150
+ * {@link buildSessionEnv}).
151
+ * Kept: everything else, notably PATH/PATHEXT/SystemRoot/HOME/USERPROFILE/
152
+ * APPDATA/LOCALAPPDATA/TEMP (hooks spawn node and resolve home dirs),
153
+ * `COPILOT_GITHUB_TOKEN`, and the remaining `COPILOT_*` (e.g. COPILOT_CLI_PATH).
154
+ */
155
+ export declare const STRIPPED_ENV_EXACT: readonly ["DISABLE_OMC", "CLAUDECODE", "CLAUDE_SESSION_ID", "CLAUDE_PLUGIN_ROOT", "NODE_OPTIONS", "COPILOT_HOME", "COPILOT_OFFLINE", "COPILOT_MODEL"];
156
+ export declare const STRIPPED_ENV_PREFIXES: readonly ["OMC_", "CLAUDE_CODE_", "COPILOT_PROVIDER_"];
157
+ /** Generic GitHub tokens dropped from the tier 1 session when a stored login was copied. */
158
+ export declare const LOGIN_SHADOWING_TOKENS: readonly ["GH_TOKEN", "GITHUB_TOKEN"];
159
+ /** Set on every copilot child (on top of COPILOT_HOME). */
160
+ export declare const SMOKE_SET_ENV: {
161
+ readonly COPILOT_ALLOW_ALL: "false";
162
+ readonly COPILOT_AUTO_UPDATE: "false";
163
+ readonly NO_COLOR: "1";
164
+ };
165
+ /** Set on the tier 1 session only: a failing hook must surface as hook.end success:false. */
166
+ export declare const SESSION_SET_ENV: {
167
+ readonly OMC_HOOK_FAIL_CLOSED: "1";
168
+ };
169
+ export declare function isStrippedEnvKey(key: string): boolean;
170
+ /** Walk up from this module to the directory holding the oh-my-copilot plugin.json. */
171
+ export declare function resolveDefaultPluginRoot(env?: NodeJS.ProcessEnv): string;
172
+ /**
173
+ * The oh-my-copilot package root that contains the running module (no env,
174
+ * no cwd fallback), or null when this code is not running from a plugin tree.
175
+ */
176
+ export declare function resolvePackageRoot(): string | null;
177
+ /** Extract the first JSON array from CLI output that may carry warnings around it. */
178
+ export declare function extractJsonArray(text: string): unknown[] | null;
179
+ export interface SessionEnvOptions {
180
+ /** Tier 1 session (adds {@link SESSION_SET_ENV}); false for the tier 0 list commands. */
181
+ session?: boolean;
182
+ /** A stored login was copied into the home: drop {@link LOGIN_SHADOWING_TOKENS}. */
183
+ hasLogin?: boolean;
184
+ }
185
+ /** Apply the env policy documented at {@link STRIPPED_ENV_EXACT}. */
186
+ export declare function buildSessionEnv(base: NodeJS.ProcessEnv, home: string, opts?: SessionEnvOptions): NodeJS.ProcessEnv;
187
+ /**
188
+ * Copy only the login identity (`loggedInUsers`, `lastLoggedInUser`) from the
189
+ * user's real config. The token stays in the OS credential store; without
190
+ * these keys an empty COPILOT_HOME falls back to `gh auth token`, whose OAuth
191
+ * app is not entitled to Copilot models ("Model ... is not available").
192
+ *
193
+ * Token precedence (`copilot help environment`, 1.0.91): COPILOT_GITHUB_TOKEN,
194
+ * GH_TOKEN, GITHUB_TOKEN each take precedence over stored credentials. So when
195
+ * a login was copied, the session drops GH_TOKEN/GITHUB_TOKEN (typically gh or
196
+ * Actions tokens, which would shadow the entitled login) and keeps
197
+ * COPILOT_GITHUB_TOKEN (an explicit Copilot opt-in). Without a stored login
198
+ * (CI) all three pass through, since a token is then the only credential.
199
+ */
200
+ export declare function loginIdentity(userConfigDir: string): Record<string, unknown>;
201
+ export interface Tier1Inputs {
202
+ exitCode: number | null;
203
+ timedOut: boolean;
204
+ error?: string;
205
+ stdout: string;
206
+ stderr: string;
207
+ timeoutMs: number;
208
+ eventsPath: string;
209
+ eventsText: string | null;
210
+ logText: string | null;
211
+ projectDir: string;
212
+ mcpServerNames: string[];
213
+ delegate: boolean;
214
+ }
215
+ /** Evaluate captured Tier 1 artifacts (exported for fixture-driven tests). */
216
+ export declare function evaluateTier1(input: Tier1Inputs): SmokeCheck[];
217
+ export declare const LIVE_RUN_REFUSED_DETAIL = "live run refused under vitest \u2014 set OMC_LIVE_SMOKE=1 (tier 1) / =2 (tier 2 scenarios)";
218
+ /**
219
+ * Hard no-billing guard: under a test runner (`VITEST` or `NODE_ENV=test` in
220
+ * the real process env) a run that would call a model (tier 1; tier 2 with
221
+ * any scenario, the default included) is refused before any subprocess or SDK
222
+ * client, unless `OMC_LIVE_SMOKE` names that tier or the test injected the
223
+ * seam that would otherwise bill (`deps.spawn` at tier 1, `deps.loadSdk` at
224
+ * tier 2). Returns the refusal detail, or null to proceed.
225
+ */
226
+ export declare function liveRunRefusal(tier: SmokeTier, scenarios: Scenario[] | undefined, deps: SmokeDeps, env?: NodeJS.ProcessEnv): string | null;
227
+ export declare function runCopilotSmoke(input?: Partial<SmokeOptions>): Promise<SmokeReport>;
228
+ //# sourceMappingURL=copilot-smoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copilot-smoke.d.ts","sourceRoot":"","sources":["../../src/smoke/copilot-smoke.ts"],"names":[],"mappings":"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"}