@stackwright-pro/mcp 0.2.0-alpha.100 → 0.2.0-alpha.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.mjs CHANGED
@@ -4121,6 +4121,67 @@ function handleValidateArtifact(input) {
4121
4121
  }
4122
4122
  return result;
4123
4123
  }
4124
+ function handleEmitEvent(input) {
4125
+ const emitFn = input._emit ?? emit;
4126
+ try {
4127
+ const caller = input.otter ?? "foreman";
4128
+ if (caller !== "foreman") {
4129
+ return {
4130
+ text: JSON.stringify({
4131
+ emitted: false,
4132
+ reason: `AUTHORIZATION: only the foreman otter may emit lifecycle events. Specialist otters should signal completion via their response text and the artifact write \u2014 not by emitting phase events. Caller was "${caller}". This is informational, not a failure.`
4133
+ }),
4134
+ isError: false
4135
+ };
4136
+ }
4137
+ let emitted = false;
4138
+ if (input.type === "phase_start") {
4139
+ if (!input.phase) {
4140
+ return {
4141
+ text: JSON.stringify({ emitted: false, reason: "phase required for phase_start" }),
4142
+ isError: false
4143
+ };
4144
+ }
4145
+ emitted = emitFn({ type: "phase_start", phase: input.phase, otter: caller });
4146
+ } else if (input.type === "phase_complete") {
4147
+ if (!input.phase) {
4148
+ return {
4149
+ text: JSON.stringify({ emitted: false, reason: "phase required for phase_complete" }),
4150
+ isError: false
4151
+ };
4152
+ }
4153
+ emitted = emitFn({
4154
+ type: "phase_complete",
4155
+ phase: input.phase,
4156
+ otter: caller,
4157
+ ...input.durationSec != null ? { durationSec: input.durationSec } : {}
4158
+ });
4159
+ } else if (input.type === "agent_invoke_start") {
4160
+ emitted = emitFn({
4161
+ type: "agent_invoke_start",
4162
+ targetOtter: input.targetOtter ?? "",
4163
+ phase: input.phase,
4164
+ otter: caller
4165
+ });
4166
+ } else if (input.type === "agent_invoke_complete") {
4167
+ emitted = emitFn({
4168
+ type: "agent_invoke_complete",
4169
+ targetOtter: input.targetOtter ?? "",
4170
+ success: input.success ?? true,
4171
+ phase: input.phase,
4172
+ otter: caller,
4173
+ ...input.durationSec != null ? { durationSec: input.durationSec } : {}
4174
+ });
4175
+ }
4176
+ return { text: JSON.stringify({ emitted }), isError: false };
4177
+ } catch (err) {
4178
+ const reason = err instanceof Error ? err.message : String(err);
4179
+ return {
4180
+ text: JSON.stringify({ emitted: false, reason: `telemetry error (non-fatal): ${reason}` }),
4181
+ isError: false
4182
+ };
4183
+ }
4184
+ }
4124
4185
  function registerPipelineTools(server2) {
4125
4186
  const DESC = "Writes state to .stackwright/ \u2014 the filesystem is the state machine.";
4126
4187
  const res = (r) => ({
@@ -4272,60 +4333,18 @@ function registerPipelineTools(server2) {
4272
4333
  );
4273
4334
  server2.tool(
4274
4335
  "stackwright_pro_emit_event",
4275
- `Emit a telemetry event to .stackwright/pipeline-events.ndjson. Foreman calls this at phase boundaries and agent-invoke boundaries. Best-effort: failures are silent and never block. ${DESC}`,
4336
+ `FOREMAN ONLY \u2014 specialist otters that call this will receive an authorization rejection (no-op, not an error). Emit a telemetry event to .stackwright/pipeline-events.ndjson. Foreman calls this at phase boundaries and agent-invoke boundaries. Best-effort: failures are silent and never block. ${DESC}`,
4276
4337
  {
4277
4338
  type: z13.enum(["phase_start", "phase_complete", "agent_invoke_start", "agent_invoke_complete"]).describe("Event type to emit"),
4278
4339
  phase: z13.string().optional().describe("Current phase name"),
4279
4340
  targetOtter: z13.string().optional().describe("For agent_invoke_* events: which otter is being invoked"),
4280
- success: z13.boolean().optional().describe("For agent_invoke_complete: did the invocation succeed?"),
4341
+ success: boolCoerce(z13.boolean().optional()).describe(
4342
+ 'For agent_invoke_complete: did the invocation succeed? (boolean; string "true"/"false" also accepted for caller tolerance)'
4343
+ ),
4281
4344
  otter: z13.string().optional().describe('Which otter is emitting (defaults to "foreman")'),
4282
4345
  durationSec: z13.number().optional().describe("Duration in seconds (for *_complete events)")
4283
4346
  },
4284
- async ({ type, phase, targetOtter, success, otter, durationSec }) => {
4285
- let emitted = false;
4286
- try {
4287
- if (type === "phase_start") {
4288
- if (!phase) {
4289
- return res({
4290
- text: JSON.stringify({ emitted: false, reason: "phase required for phase_start" }),
4291
- isError: false
4292
- });
4293
- }
4294
- emitted = emit({ type: "phase_start", phase, otter: otter ?? "foreman" });
4295
- } else if (type === "phase_complete") {
4296
- if (!phase) {
4297
- return res({
4298
- text: JSON.stringify({ emitted: false, reason: "phase required for phase_complete" }),
4299
- isError: false
4300
- });
4301
- }
4302
- emitted = emit({
4303
- type: "phase_complete",
4304
- phase,
4305
- otter: otter ?? "foreman",
4306
- ...durationSec != null ? { durationSec } : {}
4307
- });
4308
- } else if (type === "agent_invoke_start") {
4309
- emitted = emit({
4310
- type: "agent_invoke_start",
4311
- targetOtter: targetOtter ?? "",
4312
- phase,
4313
- otter: otter ?? "foreman"
4314
- });
4315
- } else if (type === "agent_invoke_complete") {
4316
- emitted = emit({
4317
- type: "agent_invoke_complete",
4318
- targetOtter: targetOtter ?? "",
4319
- success: success ?? true,
4320
- phase,
4321
- otter: otter ?? "foreman",
4322
- ...durationSec != null ? { durationSec } : {}
4323
- });
4324
- }
4325
- } catch {
4326
- }
4327
- return res({ text: JSON.stringify({ emitted }), isError: false });
4328
- }
4347
+ async ({ type, phase, targetOtter, success, otter, durationSec }) => res(handleEmitEvent({ type, phase, targetOtter, success, otter, durationSec }))
4329
4348
  );
4330
4349
  }
4331
4350
 
@@ -5798,7 +5817,7 @@ var _checksums = /* @__PURE__ */ new Map([
5798
5817
  ],
5799
5818
  [
5800
5819
  "stackwright-services-otter.json",
5801
- "8997bdd9a6fd3e6e02563578a1649480bc21acf919534ae41f73e70ade7cf500"
5820
+ "2a50ceb3fad166251d0ad8709a34a32118645713e0e34628165d16dced1d5c93"
5802
5821
  ]
5803
5822
  ]);
5804
5823
  Object.freeze(_checksums);
@@ -7552,7 +7571,7 @@ var package_default = {
7552
7571
  "test:coverage": "vitest run --coverage"
7553
7572
  },
7554
7573
  name: "@stackwright-pro/mcp",
7555
- version: "0.2.0-alpha.100",
7574
+ version: "0.2.0-alpha.101",
7556
7575
  description: "MCP tools for Stackwright Pro - Data Explorer, Security, ISR, and Dashboard generation",
7557
7576
  license: "SEE LICENSE IN LICENSE",
7558
7577
  main: "./dist/server.js",