clinkx 0.1.10 → 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 (179) hide show
  1. package/clinkx-workflows/dist/artifacts.d.ts +65 -0
  2. package/clinkx-workflows/dist/artifacts.js +268 -0
  3. package/clinkx-workflows/dist/artifacts.js.map +1 -0
  4. package/clinkx-workflows/dist/backend.d.ts +33 -0
  5. package/clinkx-workflows/dist/backend.js +9 -0
  6. package/clinkx-workflows/dist/backend.js.map +1 -0
  7. package/clinkx-workflows/dist/child-env.d.ts +23 -0
  8. package/clinkx-workflows/dist/child-env.js +53 -0
  9. package/clinkx-workflows/dist/child-env.js.map +1 -0
  10. package/clinkx-workflows/dist/clink-client.d.ts +51 -0
  11. package/clinkx-workflows/dist/clink-client.js +216 -0
  12. package/clinkx-workflows/dist/clink-client.js.map +1 -0
  13. package/clinkx-workflows/dist/config.d.ts +126 -0
  14. package/clinkx-workflows/dist/config.js +226 -0
  15. package/clinkx-workflows/dist/config.js.map +1 -0
  16. package/clinkx-workflows/dist/definition-normalizer.d.ts +59 -0
  17. package/clinkx-workflows/dist/definition-normalizer.js +75 -0
  18. package/clinkx-workflows/dist/definition-normalizer.js.map +1 -0
  19. package/clinkx-workflows/dist/engine.d.ts +235 -0
  20. package/clinkx-workflows/dist/engine.js +1044 -0
  21. package/clinkx-workflows/dist/engine.js.map +1 -0
  22. package/clinkx-workflows/dist/errors.d.ts +74 -0
  23. package/clinkx-workflows/dist/errors.js +84 -0
  24. package/clinkx-workflows/dist/errors.js.map +1 -0
  25. package/clinkx-workflows/dist/fidelity.d.ts +112 -0
  26. package/clinkx-workflows/dist/fidelity.js +140 -0
  27. package/clinkx-workflows/dist/fidelity.js.map +1 -0
  28. package/clinkx-workflows/dist/fingerprint.d.ts +69 -0
  29. package/clinkx-workflows/dist/fingerprint.js +143 -0
  30. package/clinkx-workflows/dist/fingerprint.js.map +1 -0
  31. package/clinkx-workflows/dist/index.d.ts +16 -0
  32. package/clinkx-workflows/dist/index.js +42 -0
  33. package/clinkx-workflows/dist/index.js.map +1 -0
  34. package/clinkx-workflows/dist/loader.d.ts +64 -0
  35. package/clinkx-workflows/dist/loader.js +371 -0
  36. package/clinkx-workflows/dist/loader.js.map +1 -0
  37. package/clinkx-workflows/dist/logger.d.ts +16 -0
  38. package/clinkx-workflows/dist/logger.js +31 -0
  39. package/clinkx-workflows/dist/logger.js.map +1 -0
  40. package/clinkx-workflows/dist/path-validation.d.ts +23 -0
  41. package/clinkx-workflows/dist/path-validation.js +73 -0
  42. package/clinkx-workflows/dist/path-validation.js.map +1 -0
  43. package/clinkx-workflows/dist/prompt-budget.d.ts +31 -0
  44. package/clinkx-workflows/dist/prompt-budget.js +78 -0
  45. package/clinkx-workflows/dist/prompt-budget.js.map +1 -0
  46. package/clinkx-workflows/dist/queue.d.ts +16 -0
  47. package/clinkx-workflows/dist/queue.js +46 -0
  48. package/clinkx-workflows/dist/queue.js.map +1 -0
  49. package/clinkx-workflows/dist/ranking-reducer.d.ts +11 -0
  50. package/clinkx-workflows/dist/ranking-reducer.js +245 -0
  51. package/clinkx-workflows/dist/ranking-reducer.js.map +1 -0
  52. package/clinkx-workflows/dist/reducers/index.d.ts +8 -0
  53. package/clinkx-workflows/dist/reducers/index.js +12 -0
  54. package/clinkx-workflows/dist/reducers/index.js.map +1 -0
  55. package/clinkx-workflows/dist/run-id.d.ts +17 -0
  56. package/clinkx-workflows/dist/run-id.js +26 -0
  57. package/clinkx-workflows/dist/run-id.js.map +1 -0
  58. package/clinkx-workflows/dist/run-summary/cards/council-answer.d.ts +8 -0
  59. package/clinkx-workflows/dist/run-summary/cards/council-answer.js +75 -0
  60. package/clinkx-workflows/dist/run-summary/cards/council-answer.js.map +1 -0
  61. package/clinkx-workflows/dist/run-summary/cards/council-code-review.d.ts +13 -0
  62. package/clinkx-workflows/dist/run-summary/cards/council-code-review.js +90 -0
  63. package/clinkx-workflows/dist/run-summary/cards/council-code-review.js.map +1 -0
  64. package/clinkx-workflows/dist/run-summary/cards/council-debug.d.ts +9 -0
  65. package/clinkx-workflows/dist/run-summary/cards/council-debug.js +79 -0
  66. package/clinkx-workflows/dist/run-summary/cards/council-debug.js.map +1 -0
  67. package/clinkx-workflows/dist/run-summary/cards/council-default.d.ts +11 -0
  68. package/clinkx-workflows/dist/run-summary/cards/council-default.js +57 -0
  69. package/clinkx-workflows/dist/run-summary/cards/council-default.js.map +1 -0
  70. package/clinkx-workflows/dist/run-summary/cards/council-discover.d.ts +10 -0
  71. package/clinkx-workflows/dist/run-summary/cards/council-discover.js +79 -0
  72. package/clinkx-workflows/dist/run-summary/cards/council-discover.js.map +1 -0
  73. package/clinkx-workflows/dist/run-summary/cards/generic.d.ts +2 -0
  74. package/clinkx-workflows/dist/run-summary/cards/generic.js +4 -0
  75. package/clinkx-workflows/dist/run-summary/cards/generic.js.map +1 -0
  76. package/clinkx-workflows/dist/run-summary/cards/index.d.ts +6 -0
  77. package/clinkx-workflows/dist/run-summary/cards/index.js +17 -0
  78. package/clinkx-workflows/dist/run-summary/cards/index.js.map +1 -0
  79. package/clinkx-workflows/dist/run-summary/utils.d.ts +6 -0
  80. package/clinkx-workflows/dist/run-summary/utils.js +30 -0
  81. package/clinkx-workflows/dist/run-summary/utils.js.map +1 -0
  82. package/clinkx-workflows/dist/run-summary-derived.d.ts +19 -0
  83. package/clinkx-workflows/dist/run-summary-derived.js +100 -0
  84. package/clinkx-workflows/dist/run-summary-derived.js.map +1 -0
  85. package/clinkx-workflows/dist/run-summary.d.ts +70 -0
  86. package/clinkx-workflows/dist/run-summary.js +125 -0
  87. package/clinkx-workflows/dist/run-summary.js.map +1 -0
  88. package/clinkx-workflows/dist/schema.d.ts +609 -0
  89. package/clinkx-workflows/dist/schema.js +123 -0
  90. package/clinkx-workflows/dist/schema.js.map +1 -0
  91. package/clinkx-workflows/dist/server.d.ts +16 -0
  92. package/clinkx-workflows/dist/server.js +33 -0
  93. package/clinkx-workflows/dist/server.js.map +1 -0
  94. package/clinkx-workflows/dist/shutdown.d.ts +54 -0
  95. package/clinkx-workflows/dist/shutdown.js +120 -0
  96. package/clinkx-workflows/dist/shutdown.js.map +1 -0
  97. package/clinkx-workflows/dist/state-schema.d.ts +141 -0
  98. package/clinkx-workflows/dist/state-schema.js +21 -0
  99. package/clinkx-workflows/dist/state-schema.js.map +1 -0
  100. package/clinkx-workflows/dist/state.d.ts +37 -0
  101. package/clinkx-workflows/dist/state.js +838 -0
  102. package/clinkx-workflows/dist/state.js.map +1 -0
  103. package/clinkx-workflows/dist/template-loader.d.ts +30 -0
  104. package/clinkx-workflows/dist/template-loader.js +77 -0
  105. package/clinkx-workflows/dist/template-loader.js.map +1 -0
  106. package/clinkx-workflows/dist/template.d.ts +54 -0
  107. package/clinkx-workflows/dist/template.js +128 -0
  108. package/clinkx-workflows/dist/template.js.map +1 -0
  109. package/clinkx-workflows/dist/transport.d.ts +91 -0
  110. package/clinkx-workflows/dist/transport.js +249 -0
  111. package/clinkx-workflows/dist/transport.js.map +1 -0
  112. package/clinkx-workflows/dist/types.d.ts +137 -0
  113. package/clinkx-workflows/dist/types.js +11 -0
  114. package/clinkx-workflows/dist/types.js.map +1 -0
  115. package/clinkx-workflows/dist/validators/council.d.ts +1488 -0
  116. package/clinkx-workflows/dist/validators/council.js +509 -0
  117. package/clinkx-workflows/dist/validators/council.js.map +1 -0
  118. package/clinkx-workflows/dist/validators/index.d.ts +40 -0
  119. package/clinkx-workflows/dist/validators/index.js +43 -0
  120. package/clinkx-workflows/dist/validators/index.js.map +1 -0
  121. package/clinkx-workflows/dist/workflow-receipt.d.ts +4 -0
  122. package/clinkx-workflows/dist/workflow-receipt.js +177 -0
  123. package/clinkx-workflows/dist/workflow-receipt.js.map +1 -0
  124. package/clinkx-workflows/dist/workflow-tools.d.ts +77 -0
  125. package/clinkx-workflows/dist/workflow-tools.js +1131 -0
  126. package/clinkx-workflows/dist/workflow-tools.js.map +1 -0
  127. package/clinkx-workflows/dist/workflows/council-default.d.ts +123 -0
  128. package/clinkx-workflows/dist/workflows/council-default.js +141 -0
  129. package/clinkx-workflows/dist/workflows/council-default.js.map +1 -0
  130. package/clinkx-workflows/dist/workflows/index.d.ts +12 -0
  131. package/clinkx-workflows/dist/workflows/index.js +15 -0
  132. package/clinkx-workflows/dist/workflows/index.js.map +1 -0
  133. package/conf/adapters/claude.json +13 -1
  134. package/conf/adapters/codex.json +11 -2
  135. package/conf/adapters/gemini.json +9 -0
  136. package/conf/adapters/glm.json +10 -0
  137. package/conf/adapters/hapi/claude.json +12 -2
  138. package/conf/adapters/hapi/codex.json +11 -2
  139. package/conf/adapters/hapi/gemini.json +9 -0
  140. package/conf/adapters/hapi/glm.json +10 -0
  141. package/conf/prompts/json-codereviewer.txt +6 -0
  142. package/conf/prompts/json-debug.txt +5 -0
  143. package/conf/prompts/json-default.txt +5 -0
  144. package/conf/prompts/json.txt +4 -1
  145. package/dist/config.d.ts +29 -4
  146. package/dist/config.js +23 -3
  147. package/dist/config.js.map +1 -1
  148. package/dist/handler.d.ts +2 -0
  149. package/dist/handler.js +2 -1
  150. package/dist/handler.js.map +1 -1
  151. package/dist/local-clink-backend.d.ts +30 -0
  152. package/dist/local-clink-backend.js +106 -0
  153. package/dist/local-clink-backend.js.map +1 -0
  154. package/dist/parsers/claude-stream-json.d.ts +1 -1
  155. package/dist/parsers/claude-stream-json.js +26 -8
  156. package/dist/parsers/claude-stream-json.js.map +1 -1
  157. package/dist/parsers/extract.d.ts +2 -0
  158. package/dist/parsers/extract.js +46 -20
  159. package/dist/parsers/extract.js.map +1 -1
  160. package/dist/pipeline.d.ts +2 -4
  161. package/dist/pipeline.js +246 -31
  162. package/dist/pipeline.js.map +1 -1
  163. package/dist/prompt.js +8 -1
  164. package/dist/prompt.js.map +1 -1
  165. package/dist/registry.d.ts +4 -0
  166. package/dist/registry.js +14 -0
  167. package/dist/registry.js.map +1 -1
  168. package/dist/result-contract.d.ts +6 -1
  169. package/dist/result-contract.js +10 -22
  170. package/dist/result-contract.js.map +1 -1
  171. package/dist/runner.js +59 -12
  172. package/dist/runner.js.map +1 -1
  173. package/dist/schema.d.ts +20 -0
  174. package/dist/schema.js +29 -2
  175. package/dist/schema.js.map +1 -1
  176. package/dist/server.d.ts +3 -3
  177. package/dist/server.js +119 -45
  178. package/dist/server.js.map +1 -1
  179. package/package.json +12 -5
package/dist/config.d.ts CHANGED
@@ -2,12 +2,18 @@ import { z } from "zod";
2
2
  declare const RoleConfigSchema: z.ZodObject<{
3
3
  inline_prompt: z.ZodOptional<z.ZodString>;
4
4
  prompt_file: z.ZodOptional<z.ZodString>;
5
+ parser: z.ZodOptional<z.ZodEnum<["text", "json_extract", "gemini_json", "codex_jsonl", "claude_json", "claude_stream_json"]>>;
6
+ extra_args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
5
7
  }, "strip", z.ZodTypeAny, {
6
8
  inline_prompt?: string | undefined;
7
9
  prompt_file?: string | undefined;
10
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
11
+ extra_args?: string[] | undefined;
8
12
  }, {
9
13
  inline_prompt?: string | undefined;
10
14
  prompt_file?: string | undefined;
15
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
16
+ extra_args?: string[] | undefined;
11
17
  }>;
12
18
  export type RoleConfig = z.infer<typeof RoleConfigSchema>;
13
19
  /**
@@ -34,12 +40,18 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
34
40
  roles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
35
41
  inline_prompt: z.ZodOptional<z.ZodString>;
36
42
  prompt_file: z.ZodOptional<z.ZodString>;
43
+ parser: z.ZodOptional<z.ZodEnum<["text", "json_extract", "gemini_json", "codex_jsonl", "claude_json", "claude_stream_json"]>>;
44
+ extra_args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
37
45
  }, "strip", z.ZodTypeAny, {
38
46
  inline_prompt?: string | undefined;
39
47
  prompt_file?: string | undefined;
48
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
49
+ extra_args?: string[] | undefined;
40
50
  }, {
41
51
  inline_prompt?: string | undefined;
42
52
  prompt_file?: string | undefined;
53
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
54
+ extra_args?: string[] | undefined;
43
55
  }>>>;
44
56
  supports_images: z.ZodDefault<z.ZodBoolean>;
45
57
  requires_tty: z.ZodDefault<z.ZodBoolean>;
@@ -57,7 +69,9 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
57
69
  stdin_placeholder_arg: z.ZodOptional<z.ZodString>;
58
70
  native_output_file_flag: z.ZodOptional<z.ZodString>;
59
71
  suppress_stdout: z.ZodDefault<z.ZodBoolean>;
72
+ stderr_to_file: z.ZodDefault<z.ZodBoolean>;
60
73
  }, "strip", z.ZodTypeAny, {
74
+ parser: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json";
61
75
  name: string;
62
76
  command: string;
63
77
  args: string[];
@@ -65,11 +79,12 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
65
79
  env: Record<string, string>;
66
80
  env_allowlist: string[];
67
81
  timeout_seconds: number;
68
- parser: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json";
69
82
  tolerate_nonzero_exit_for_parse: boolean;
70
83
  roles: Record<string, {
71
84
  inline_prompt?: string | undefined;
72
85
  prompt_file?: string | undefined;
86
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
87
+ extra_args?: string[] | undefined;
73
88
  }>;
74
89
  supports_images: boolean;
75
90
  requires_tty: boolean;
@@ -79,6 +94,7 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
79
94
  };
80
95
  prompt_mode: "stdin" | "arg" | "file";
81
96
  suppress_stdout: boolean;
97
+ stderr_to_file: boolean;
82
98
  runner?: string | undefined;
83
99
  idle_timeout_seconds?: number | undefined;
84
100
  idle_timeout_startup_seconds?: number | undefined;
@@ -88,6 +104,7 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
88
104
  }, {
89
105
  name: string;
90
106
  command: string;
107
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
91
108
  runner?: string | undefined;
92
109
  args?: string[] | undefined;
93
110
  unsafe_args?: string[] | undefined;
@@ -96,12 +113,13 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
96
113
  timeout_seconds?: number | undefined;
97
114
  idle_timeout_seconds?: number | undefined;
98
115
  idle_timeout_startup_seconds?: number | undefined;
99
- parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
100
116
  tolerate_nonzero_exit_for_parse?: boolean | undefined;
101
117
  capabilities_hint?: string | undefined;
102
118
  roles?: Record<string, {
103
119
  inline_prompt?: string | undefined;
104
120
  prompt_file?: string | undefined;
121
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
122
+ extra_args?: string[] | undefined;
105
123
  }> | undefined;
106
124
  supports_images?: boolean | undefined;
107
125
  requires_tty?: boolean | undefined;
@@ -113,7 +131,9 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
113
131
  stdin_placeholder_arg?: string | undefined;
114
132
  native_output_file_flag?: string | undefined;
115
133
  suppress_stdout?: boolean | undefined;
134
+ stderr_to_file?: boolean | undefined;
116
135
  }>, {
136
+ parser: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json";
117
137
  name: string;
118
138
  command: string;
119
139
  args: string[];
@@ -121,11 +141,12 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
121
141
  env: Record<string, string>;
122
142
  env_allowlist: string[];
123
143
  timeout_seconds: number;
124
- parser: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json";
125
144
  tolerate_nonzero_exit_for_parse: boolean;
126
145
  roles: Record<string, {
127
146
  inline_prompt?: string | undefined;
128
147
  prompt_file?: string | undefined;
148
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
149
+ extra_args?: string[] | undefined;
129
150
  }>;
130
151
  supports_images: boolean;
131
152
  requires_tty: boolean;
@@ -135,6 +156,7 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
135
156
  };
136
157
  prompt_mode: "stdin" | "arg" | "file";
137
158
  suppress_stdout: boolean;
159
+ stderr_to_file: boolean;
138
160
  runner?: string | undefined;
139
161
  idle_timeout_seconds?: number | undefined;
140
162
  idle_timeout_startup_seconds?: number | undefined;
@@ -144,6 +166,7 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
144
166
  }, {
145
167
  name: string;
146
168
  command: string;
169
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
147
170
  runner?: string | undefined;
148
171
  args?: string[] | undefined;
149
172
  unsafe_args?: string[] | undefined;
@@ -152,12 +175,13 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
152
175
  timeout_seconds?: number | undefined;
153
176
  idle_timeout_seconds?: number | undefined;
154
177
  idle_timeout_startup_seconds?: number | undefined;
155
- parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
156
178
  tolerate_nonzero_exit_for_parse?: boolean | undefined;
157
179
  capabilities_hint?: string | undefined;
158
180
  roles?: Record<string, {
159
181
  inline_prompt?: string | undefined;
160
182
  prompt_file?: string | undefined;
183
+ parser?: "text" | "json_extract" | "gemini_json" | "codex_jsonl" | "claude_json" | "claude_stream_json" | undefined;
184
+ extra_args?: string[] | undefined;
161
185
  }> | undefined;
162
186
  supports_images?: boolean | undefined;
163
187
  requires_tty?: boolean | undefined;
@@ -169,6 +193,7 @@ export declare const CliAdapterConfigSchema: z.ZodEffects<z.ZodObject<{
169
193
  stdin_placeholder_arg?: string | undefined;
170
194
  native_output_file_flag?: string | undefined;
171
195
  suppress_stdout?: boolean | undefined;
196
+ stderr_to_file?: boolean | undefined;
172
197
  }>;
173
198
  export type CliAdapterConfig = z.infer<typeof CliAdapterConfigSchema>;
174
199
  export {};
package/dist/config.js CHANGED
@@ -1,7 +1,12 @@
1
1
  import { z } from "zod";
2
+ const ParserNameSchema = z.enum([
3
+ "text", "json_extract", "gemini_json", "codex_jsonl", "claude_json", "claude_stream_json",
4
+ ]);
2
5
  const RoleConfigSchema = z.object({
3
6
  inline_prompt: z.string().optional(),
4
7
  prompt_file: z.string().optional(),
8
+ parser: ParserNameSchema.optional(),
9
+ extra_args: z.array(z.string()).optional(),
5
10
  });
6
11
  const ResultContractSchema = z.object({
7
12
  enabled: z.boolean().default(false),
@@ -25,9 +30,7 @@ export const CliAdapterConfigSchema = z.object({
25
30
  timeout_seconds: z.number().positive().default(600),
26
31
  idle_timeout_seconds: z.number().nonnegative().optional(),
27
32
  idle_timeout_startup_seconds: z.number().nonnegative().optional(),
28
- parser: z
29
- .enum(["text", "json_extract", "gemini_json", "codex_jsonl", "claude_json", "claude_stream_json"])
30
- .default("text"),
33
+ parser: ParserNameSchema.default("text"),
31
34
  tolerate_nonzero_exit_for_parse: z.boolean().default(false),
32
35
  capabilities_hint: z.string().optional(),
33
36
  roles: z.record(RoleConfigSchema).default({}),
@@ -41,6 +44,7 @@ export const CliAdapterConfigSchema = z.object({
41
44
  stdin_placeholder_arg: z.string().min(1).optional(),
42
45
  native_output_file_flag: z.string().min(1).optional(),
43
46
  suppress_stdout: z.boolean().default(false),
47
+ stderr_to_file: z.boolean().default(false),
44
48
  }).superRefine((data, ctx) => {
45
49
  if (data.suppress_stdout && !data.native_output_file_flag) {
46
50
  ctx.addIssue({
@@ -56,5 +60,21 @@ export const CliAdapterConfigSchema = z.object({
56
60
  path: ["native_output_file_flag"],
57
61
  });
58
62
  }
63
+ if (data.stderr_to_file) {
64
+ if ((data.idle_timeout_seconds ?? 0) > 0) {
65
+ ctx.addIssue({
66
+ code: z.ZodIssueCode.custom,
67
+ message: "stderr_to_file is incompatible with idle_timeout_seconds > 0 (stderr data events are needed for idle detection)",
68
+ path: ["stderr_to_file"],
69
+ });
70
+ }
71
+ if ((data.idle_timeout_startup_seconds ?? 0) > 0) {
72
+ ctx.addIssue({
73
+ code: z.ZodIssueCode.custom,
74
+ message: "stderr_to_file is incompatible with idle_timeout_startup_seconds > 0 (stderr data events are needed for idle detection)",
75
+ path: ["stderr_to_file"],
76
+ });
77
+ }
78
+ }
59
79
  });
60
80
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/handler.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { AdapterRegistry } from "./registry.js";
1
2
  import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
3
  /**
3
4
  * Handle a clink tool invocation.
@@ -12,6 +13,7 @@ export declare function handleClink(rawInput: unknown, options?: {
12
13
  server: Server;
13
14
  token: string | number;
14
15
  };
16
+ registry?: AdapterRegistry;
15
17
  }): Promise<{
16
18
  content: Array<{
17
19
  type: "text";
package/dist/handler.js CHANGED
@@ -34,12 +34,13 @@ export async function handleClink(rawInput, options) {
34
34
  }
35
35
  const input = parseResult.data;
36
36
  logger.debug({ cli_name: input.cli_name, role: input.role }, "clink invoked");
37
+ const effectiveRegistry = options?.registry ?? getRegistry();
37
38
  const pipelineOptions = options?.signal != null || options?.progress != null
38
39
  ? {
39
40
  ...(options?.signal != null ? { signal: options.signal } : {}),
40
41
  ...(options?.progress != null ? { progress: options.progress } : {}),
41
42
  }
42
43
  : undefined;
43
- return await executePipeline(input, getRegistry(), pipelineOptions);
44
+ return await executePipeline(input, effectiveRegistry, pipelineOptions);
44
45
  }
45
46
  //# sourceMappingURL=handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,SAAS,cAAc,CAAC,GAAa;IACnC,OAAO,GAAG,CAAC,MAAM;SACd,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrE,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IACrC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,iCAAiC;AACjC,IAAI,QAAqC,CAAC;AAE1C,SAAS,WAAW;IAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAiB,EACjB,OAGC;IAKD,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,IAAI,kBAAkB,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC;IAC/B,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC;IAE9E,MAAM,eAAe,GACnB,OAAO,EAAE,MAAM,IAAI,IAAI,IAAI,OAAO,EAAE,QAAQ,IAAI,IAAI;QAClD,CAAC,CAAC;YACE,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE;QACH,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO,MAAM,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE,eAAe,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,SAAS,cAAc,CAAC,GAAa;IACnC,OAAO,GAAG,CAAC,MAAM;SACd,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrE,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IACrC,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,iCAAiC;AACjC,IAAI,QAAqC,CAAC;AAE1C,SAAS,WAAW;IAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAiB,EACjB,OAIC;IAKD,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACzD,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QACjD,MAAM,IAAI,kBAAkB,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC;IAC/B,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,eAAe,CAAC,CAAC;IAE9E,MAAM,iBAAiB,GAAG,OAAO,EAAE,QAAQ,IAAI,WAAW,EAAE,CAAC;IAC7D,MAAM,eAAe,GACnB,OAAO,EAAE,MAAM,IAAI,IAAI,IAAI,OAAO,EAAE,QAAQ,IAAI,IAAI;QAClD,CAAC,CAAC;YACE,GAAG,CAAC,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE;QACH,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO,MAAM,eAAe,CAAC,KAAK,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * In-process ClinkBackend that calls handleClink() directly.
3
+ *
4
+ * Eliminates child process + MCP transport overhead by routing workflow
5
+ * engine calls straight into the root pipeline. The existing semaphore
6
+ * in pipeline.ts handles concurrency; the engine's DispatchQueue provides
7
+ * the outer rate limit.
8
+ */
9
+ import type { ClinkBackend, ToolCallResult } from "../clinkx-workflows/dist/backend.js";
10
+ import type { AdapterRegistry } from "./registry.js";
11
+ export interface LocalClinkBackendOptions {
12
+ readonly registry?: AdapterRegistry | undefined;
13
+ readonly defaultMaxResponseChars?: number | undefined;
14
+ }
15
+ export declare class LocalClinkBackend implements ClinkBackend {
16
+ readonly cliNames: string[];
17
+ readonly roleNames: string[];
18
+ private terminated;
19
+ private readonly registry;
20
+ private readonly defaultMaxResponseChars;
21
+ constructor(cliNames: string[], roleNames: string[], options?: LocalClinkBackendOptions);
22
+ get isTerminated(): boolean;
23
+ get hasChildDied(): boolean;
24
+ connect(): Promise<void>;
25
+ callTool(args: Record<string, unknown>, options?: {
26
+ signal?: AbortSignal;
27
+ timeoutMs?: number;
28
+ }): Promise<ToolCallResult>;
29
+ terminate(): Promise<void>;
30
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * In-process ClinkBackend that calls handleClink() directly.
3
+ *
4
+ * Eliminates child process + MCP transport overhead by routing workflow
5
+ * engine calls straight into the root pipeline. The existing semaphore
6
+ * in pipeline.ts handles concurrency; the engine's DispatchQueue provides
7
+ * the outer rate limit.
8
+ */
9
+ import { WorkflowCancellationError } from "../clinkx-workflows/dist/errors.js";
10
+ import { handleClink } from "./handler.js";
11
+ import { CancellationError, InvalidParamsError } from "./errors.js";
12
+ import { logger } from "./logger.js";
13
+ export class LocalClinkBackend {
14
+ cliNames;
15
+ roleNames;
16
+ terminated = false;
17
+ registry;
18
+ defaultMaxResponseChars;
19
+ constructor(cliNames, roleNames, options) {
20
+ this.cliNames = cliNames;
21
+ this.roleNames = roleNames;
22
+ this.registry = options?.registry;
23
+ this.defaultMaxResponseChars = options?.defaultMaxResponseChars;
24
+ }
25
+ get isTerminated() {
26
+ return this.terminated;
27
+ }
28
+ get hasChildDied() {
29
+ // No child process — can never die unexpectedly
30
+ return false;
31
+ }
32
+ async connect() {
33
+ // No-op: in-process backend needs no handshake
34
+ logger.debug("LocalClinkBackend: connect (no-op)");
35
+ }
36
+ async callTool(args, options) {
37
+ if (this.terminated) {
38
+ throw new Error("LocalClinkBackend: already terminated");
39
+ }
40
+ // Compose timeout with existing signal for Layer 2 deadline enforcement.
41
+ // handleClink() only accepts AbortSignal, not a separate timeoutMs param,
42
+ // so we fold the deadline into a composite signal via AbortSignal.any().
43
+ let signal = options?.signal;
44
+ if (options?.timeoutMs != null) {
45
+ const timeoutSignal = AbortSignal.timeout(options.timeoutMs);
46
+ signal = signal != null
47
+ ? AbortSignal.any([signal, timeoutSignal])
48
+ : timeoutSignal;
49
+ }
50
+ // Task 3: Inject workflow-default max_response_chars if not already set.
51
+ let effectiveArgs = args;
52
+ if (this.defaultMaxResponseChars != null && args["max_response_chars"] == null) {
53
+ effectiveArgs = { ...args, max_response_chars: this.defaultMaxResponseChars };
54
+ }
55
+ // handleClink() validates input, acquires semaphore, runs pipeline,
56
+ // and returns the standard MCP tool result shape.
57
+ try {
58
+ const result = await handleClink(effectiveArgs, {
59
+ ...(signal != null ? { signal } : {}),
60
+ ...(this.registry != null ? { registry: this.registry } : {}),
61
+ });
62
+ return result;
63
+ }
64
+ catch (error) {
65
+ // Translate root error types to workflow-engine-expected types.
66
+ // handleClink() throws root CancellationError / InvalidParamsError,
67
+ // but the workflow engine (clink-client.ts) expects:
68
+ // - WorkflowCancellationError for cancellations
69
+ // - errors with code === -32602 for InvalidParams (isMcpInvalidParams check)
70
+ if (error instanceof CancellationError) {
71
+ // Distinguish per-call timeout from user cancellation.
72
+ // When AbortSignal.timeout() fires, the signal's reason is a TimeoutError —
73
+ // that should surface as a retriable error, not a halt-inducing cancellation.
74
+ if (signal?.reason instanceof Error && signal.reason.name === "TimeoutError") {
75
+ // Task 2: Return isError + _debug metadata so clink-client.ts classifies
76
+ // the timeout as transient (termination_reason: "wall" → retryable).
77
+ // Previously this threw a plain Error, which classifyFailureClass() in
78
+ // engine.ts treated as permanent — wrong for timeouts.
79
+ const timeoutText = `Per-call timeout exceeded (${String(options?.timeoutMs ?? "unknown")}ms)`;
80
+ return {
81
+ content: [
82
+ { type: "text", text: timeoutText },
83
+ { type: "text", text: JSON.stringify({ _debug: { termination_reason: "wall" } }) },
84
+ ],
85
+ isError: true,
86
+ };
87
+ }
88
+ throw new WorkflowCancellationError();
89
+ }
90
+ if (error instanceof InvalidParamsError) {
91
+ // clink-client.ts checks (err as any).code === -32602
92
+ const translated = new Error(error.message, { cause: error });
93
+ translated.code = -32602;
94
+ throw translated;
95
+ }
96
+ throw error;
97
+ }
98
+ }
99
+ async terminate() {
100
+ if (this.terminated)
101
+ return;
102
+ this.terminated = true;
103
+ logger.debug("LocalClinkBackend: terminated");
104
+ }
105
+ }
106
+ //# sourceMappingURL=local-clink-backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-clink-backend.js","sourceRoot":"","sources":["../src/local-clink-backend.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import type { Parser } from "./types.js";
8
8
  * - type:"result", subtype:"success" — final result string (canonical)
9
9
  *
10
10
  * Extraction strategy:
11
- * 1. Find last `type=result` event → use its `result` field
11
+ * 1. Find first non-empty `type=result` event → use its `result` field (first-result-wins)
12
12
  * 2. Fallback: find last `type=assistant` event → extract message.content[].text
13
13
  */
14
14
  export declare const claudeStreamJsonParser: Parser;
@@ -39,14 +39,14 @@ function extractAssistantText(value) {
39
39
  * - type:"result", subtype:"success" — final result string (canonical)
40
40
  *
41
41
  * Extraction strategy:
42
- * 1. Find last `type=result` event → use its `result` field
42
+ * 1. Find first non-empty `type=result` event → use its `result` field (first-result-wins)
43
43
  * 2. Fallback: find last `type=assistant` event → extract message.content[].text
44
44
  */
45
45
  export const claudeStreamJsonParser = {
46
46
  name: "claude_stream_json",
47
- preferredBuffers: ["stdoutTail", "stdoutHead"],
47
+ preferredBuffers: ["stdoutHead", "stdoutTail"],
48
48
  parse(input) {
49
- const text = preferredText(input, ["stdoutTail", "stdoutHead"]);
49
+ const text = preferredText(input, ["stdoutHead", "stdoutTail"]);
50
50
  if (text.trim().length === 0)
51
51
  return null;
52
52
  const lines = text
@@ -54,7 +54,10 @@ export const claudeStreamJsonParser = {
54
54
  .map((l) => l.trim())
55
55
  .filter((l) => l.length > 0);
56
56
  let resultText = null;
57
+ let resultLatched = false;
58
+ let resultEventCount = 0;
57
59
  let lastAssistantText = null;
60
+ let assistantEventCount = 0;
58
61
  for (const line of lines) {
59
62
  let parsed;
60
63
  try {
@@ -66,25 +69,40 @@ export const claudeStreamJsonParser = {
66
69
  if (parsed == null || typeof parsed !== "object")
67
70
  continue;
68
71
  const rec = parsed;
69
- // Primary: type=result event with result field
72
+ // Primary: first non-empty type=result event wins (subsequent are ignored)
70
73
  if (rec["type"] === "result" && typeof rec["result"] === "string") {
71
- resultText = rec["result"];
74
+ resultEventCount++;
75
+ const candidate = rec["result"];
76
+ if (candidate.trim().length > 0) {
77
+ if (resultText == null) {
78
+ resultText = candidate;
79
+ }
80
+ else {
81
+ resultLatched = true;
82
+ }
83
+ }
72
84
  }
73
- // Fallback: type=assistant event
85
+ // Fallback: type=assistant event (last-wins — multi-turn sessions have many)
74
86
  const assistantText = extractAssistantText(parsed);
75
87
  if (assistantText != null) {
88
+ assistantEventCount++;
76
89
  lastAssistantText = assistantText;
77
90
  }
78
91
  }
79
92
  // Prefer result event, but treat empty/whitespace-only result as absent
80
93
  // so we fall through to lastAssistantText via ??.
81
- const content = (resultText && resultText.trim().length > 0 ? resultText : null) ?? lastAssistantText;
94
+ const content = resultText ?? lastAssistantText;
82
95
  if (content == null || content.trim().length === 0)
83
96
  return null;
84
97
  return {
85
98
  content,
86
99
  source: "parser",
87
- metadata: { parser: "claude_stream_json" },
100
+ metadata: {
101
+ parser: "claude_stream_json",
102
+ resultEventCount,
103
+ resultLatched,
104
+ assistantEventCount,
105
+ },
88
106
  };
89
107
  },
90
108
  };
@@ -1 +1 @@
1
- {"version":3,"file":"claude-stream-json.js","sourceRoot":"","sources":["../../src/parsers/claude-stream-json.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claude-stream-json.js","sourceRoot":"","sources":["../../src/parsers/claude-stream-json.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { ParseInput, ParseResult } from "./types.js";
2
+ import { type ResultContractStatus } from "../result-contract.js";
2
3
  export interface ExtractInput extends ParseInput {
3
4
  exitCode: number | null;
4
5
  /**
@@ -11,6 +12,7 @@ export interface ExtractOutput {
11
12
  result: ParseResult;
12
13
  isError: boolean;
13
14
  exitCode: number | null;
15
+ resultContractStatus?: ResultContractStatus;
14
16
  }
15
17
  /**
16
18
  * Deterministically extract the final user-facing content from captured buffers.
@@ -22,9 +22,9 @@ function parserByName(name) {
22
22
  }
23
23
  async function tryReadResultContract(workdir, contract) {
24
24
  if (!contract?.enabled)
25
- return null;
25
+ return { content: null, status: "disabled" };
26
26
  if (contract.filename.trim().length === 0)
27
- return null;
27
+ return { content: null, status: "missing" };
28
28
  return readResultFile(workdir, contract.filename);
29
29
  }
30
30
  function rawStdoutFallback(input) {
@@ -57,30 +57,42 @@ function hasValidPayload(result) {
57
57
  * 6) raw stderr fallback (when stdout is empty)
58
58
  */
59
59
  export async function extractResult(input) {
60
- const contractText = await tryReadResultContract(input.workdir, input.adapter.result_contract);
60
+ const contractOutcome = await tryReadResultContract(input.workdir, input.adapter.result_contract);
61
+ const contractText = contractOutcome.content;
61
62
  let result = contractText != null
62
63
  ? {
63
64
  content: contractText,
64
65
  source: "result_contract",
65
- metadata: { filename: input.adapter.result_contract?.filename },
66
+ metadata: {
67
+ filename: input.adapter.result_contract?.filename,
68
+ result_contract_status: contractOutcome.status,
69
+ },
66
70
  }
67
71
  : null;
68
- // When stdout is intentionally suppressed and the native output file is missing, hard fail.
69
- // Falling through to the parser chain would produce a silent false success because
70
- // stdout buffers are empty ("ignore" stdio) and the text parser returns "".
71
- if (result == null && input.adapter.suppress_stdout && input.adapter.result_contract?.enabled) {
72
- return {
73
- result: {
74
- content: "",
75
- source: "result_contract",
76
- metadata: {
77
- parse_status: "invalid",
78
- rejection_reason: "missing_result_contract_file",
72
+ // When the result contract is enabled but missing, hard fail on exit-0
73
+ // unless stdout carries a viable fallback payload.
74
+ if (result == null &&
75
+ input.adapter.result_contract?.enabled &&
76
+ input.exitCode === 0) {
77
+ const stdoutCombined = (input.stdoutHead + input.stdoutTail).trim();
78
+ if (stdoutCombined.length === 0) {
79
+ return {
80
+ result: {
81
+ content: "",
82
+ source: "result_contract",
83
+ metadata: {
84
+ parse_status: "invalid",
85
+ rejection_reason: contractOutcome.status === "missing"
86
+ ? "missing_result_contract_file"
87
+ : `result_contract_${contractOutcome.status}`,
88
+ result_contract_status: contractOutcome.status,
89
+ },
79
90
  },
80
- },
81
- isError: true,
82
- exitCode: input.exitCode,
83
- };
91
+ isError: true,
92
+ exitCode: input.exitCode,
93
+ resultContractStatus: contractOutcome.status,
94
+ };
95
+ }
84
96
  }
85
97
  if (result == null) {
86
98
  const adapterParser = parserByName(input.adapter.parser);
@@ -115,6 +127,17 @@ export async function extractResult(input) {
115
127
  effectiveResult = stderrResult;
116
128
  }
117
129
  }
130
+ // Surface parser diagnostics (Fix 3: extraction diagnostics)
131
+ const parserMeta = effectiveResult.metadata ?? {};
132
+ const resultLatched = parserMeta["resultLatched"] === true;
133
+ if (resultLatched) {
134
+ logger.warn({
135
+ adapter: input.adapter.name,
136
+ parser: input.adapter.parser,
137
+ resultEventCount: parserMeta["resultEventCount"],
138
+ assistantEventCount: parserMeta["assistantEventCount"],
139
+ }, "multiple result events detected — first-result-wins latched, late results ignored (background task bug pattern)");
140
+ }
118
141
  logger.debug({
119
142
  adapter: input.adapter.name,
120
143
  parser: input.adapter.parser,
@@ -124,6 +147,9 @@ export async function extractResult(input) {
124
147
  stdoutTailLen: input.stdoutTail.length,
125
148
  stderrHeadLen: input.stderrHead.length,
126
149
  stderrTailLen: input.stderrTail.length,
150
+ resultEventCount: parserMeta["resultEventCount"],
151
+ resultLatched,
152
+ assistantEventCount: parserMeta["assistantEventCount"],
127
153
  }, "extraction complete");
128
154
  // Error recovery parity: always attempt extraction, even on non-zero exit.
129
155
  const exitCode = input.exitCode;
@@ -138,6 +164,6 @@ export async function extractResult(input) {
138
164
  : tolerate && hasValidPayload(effectiveResult)
139
165
  ? false
140
166
  : true;
141
- return { result: effectiveResult, isError, exitCode };
167
+ return { result: effectiveResult, isError, exitCode, resultContractStatus: contractOutcome.status };
142
168
  }
143
169
  //# sourceMappingURL=extract.js.map