@oisincoveney/pipeline 1.10.0 → 1.10.2

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/README.md CHANGED
@@ -300,7 +300,7 @@ The installer creates one command surface per configured entrypoint.
300
300
  | Host | Generated files | Invocation |
301
301
  | ----------- | ----------------------------------------------------------------- | ---------------------------------- |
302
302
  | Claude Code | `.claude/commands/<entrypoint>.md`, `.claude/agents/*.md` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
303
- | Codex | `.agents/skills/<entrypoint>/SKILL.md`, `.codex/agents/*.toml` | `$pipe <task>`, `$inspect <task>`, `$epic <task>` |
303
+ | Codex | `.agents/skills/<entrypoint>/SKILL.md`, `.agents/plugins/oisin-pipeline/commands/<entrypoint>.md`, `.agents/plugins/oisin-pipeline/agents/*.md`, `.codex/config.toml` | `$pipe <task>`, `$inspect <task>`, `$epic <task>`, `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
304
304
  | OpenCode | `.opencode/commands/<entrypoint>.md`, `.opencode/agents/*.md` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
305
305
  | Kimi | `.kimi/commands/<entrypoint>.md`, `.kimi/agents/*.yaml` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
306
306
  | Pi | `.pi/prompts/<entrypoint>.md` | `/pipe <task>`, `/inspect <task>`, `/epic <task>` |
package/dist/config.d.ts CHANGED
@@ -4,7 +4,7 @@ import { z } from "zod";
4
4
  declare const PIPELINE_CONFIG_PATH = ".pipeline/pipeline.yaml";
5
5
  declare const RUNNERS_CONFIG_PATH = ".pipeline/runners.yaml";
6
6
  declare const PROFILES_CONFIG_PATH = ".pipeline/profiles.yaml";
7
- declare const RUNNER_TYPES: readonly ["claude", "codex", "opencode", "kimi", "pi", "command"];
7
+ declare const RUNNER_TYPES: readonly ["codex", "opencode", "command"];
8
8
  declare const NODE_KINDS: readonly ["agent", "command", "builtin", "group", "parallel", "workflow"];
9
9
  declare const HOOK_EVENTS: readonly ["workflow.start", "workflow.success", "workflow.failure", "workflow.complete", "node.start", "node.success", "node.error", "gate.failure"];
10
10
  declare const GATE_KINDS: readonly ["acceptance", "artifact", "builtin", "changed_files", "command", "json_schema", "verdict"];
@@ -271,11 +271,8 @@ declare const configSchema: z.ZodObject<{
271
271
  model: z.ZodOptional<z.ZodString>;
272
272
  type: z.ZodEnum<{
273
273
  command: "command";
274
- claude: "claude";
275
274
  codex: "codex";
276
275
  opencode: "opencode";
277
- kimi: "kimi";
278
- pi: "pi";
279
276
  }>;
280
277
  }, z.core.$strict>>>;
281
278
  skills: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
package/dist/config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { resolveFileReference } from "./path-refs.js";
2
+ import { parseJson } from "./safe-json.js";
2
3
  import { existsSync, readFileSync } from "node:fs";
3
4
  import { join } from "node:path";
4
5
  import { parseDocument } from "yaml";
@@ -10,11 +11,8 @@ const PROFILES_CONFIG_PATH = ".pipeline/profiles.yaml";
10
11
  const LEGACY_CONFIG_PATH = ".pipeline/config.toml";
11
12
  const ID_RE = /^[a-z][a-z0-9-]*$/;
12
13
  const RUNNER_TYPES = [
13
- "claude",
14
14
  "codex",
15
15
  "opencode",
16
- "kimi",
17
- "pi",
18
16
  "command"
19
17
  ];
20
18
  const HOOK_EVENTS = [
@@ -452,7 +450,7 @@ function resolveMcpServerRef(id, ref, projectRoot) {
452
450
  function parseMcpJsonFile(id, ref, filePath) {
453
451
  let raw;
454
452
  try {
455
- raw = JSON.parse(readFileSync(filePath, "utf8"));
453
+ raw = parseJson(readFileSync(filePath, "utf8"), `MCP config ${ref.path}`);
456
454
  } catch (err) {
457
455
  throw new PipelineConfigError("PIPELINE_CONFIG_PARSE_ERROR", `Failed to parse MCP config ${ref.path}`, [{
458
456
  path: `mcp_servers.${id}.ref.path`,
package/dist/gates.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { parseJson } from "./safe-json.js";
1
2
  import { existsSync, readFileSync } from "node:fs";
2
3
  import { join } from "node:path";
3
4
  import { execa } from "execa";
@@ -13,7 +14,7 @@ function parseFailingTests(output) {
13
14
  }
14
15
  function readPackageScripts(worktreePath) {
15
16
  try {
16
- return JSON.parse(readFileSync(join(worktreePath, "package.json"), "utf-8")).scripts ?? {};
17
+ return parseJson(readFileSync(join(worktreePath, "package.json"), "utf-8"), "package.json").scripts ?? {};
17
18
  } catch {
18
19
  return {};
19
20
  }
@@ -136,19 +137,16 @@ const JSCPD_DEFAULT_IGNORES = [
136
137
  "**/.next/**",
137
138
  "**/.turbo/**",
138
139
  "**/.cache/**",
139
- "**/.claude/**",
140
140
  "**/.codex/**",
141
- "**/.kimi/**",
142
141
  "**/.serena/**",
143
142
  "**/.opencode/**",
144
- "**/.pi/**",
145
143
  "**/.pipeline/host-resources/**",
146
144
  "**/.pipeline/skills/**",
147
145
  "**/.agents/skills/**"
148
146
  ];
149
147
  function parseJscpdOutput(output) {
150
148
  try {
151
- return { violations: (JSON.parse(output)?.duplicates ?? []).map((dup) => ({
149
+ return { violations: (parseJson(output, "jscpd output")?.duplicates ?? []).map((dup) => ({
152
150
  file: dup?.firstFile?.name ?? "unknown",
153
151
  line: dup?.firstFile?.start,
154
152
  message: `Duplicate code block detected between ${dup?.firstFile?.name} and ${dup?.secondFile?.name}`
package/dist/index.js CHANGED
@@ -50,7 +50,7 @@ function formatRuntimeProgress(event) {
50
50
  console.error(message);
51
51
  }
52
52
  function formatRuntimeProgressMessage(event) {
53
- return formatWorkflowProgress(event) ?? formatAgentProgress(event) ?? formatCheckProgress(event) ?? formatRepairProgress(event);
53
+ return formatWorkflowProgress(event) ?? formatAgentProgress(event) ?? formatCheckProgress(event) ?? formatObservabilityProgress(event) ?? formatRepairProgress(event);
54
54
  }
55
55
  function formatWorkflowProgress(event) {
56
56
  switch (event.type) {
@@ -92,6 +92,12 @@ function formatRepairProgress(event) {
92
92
  default: throw new Error(`Unhandled runtime event: ${event.type}`);
93
93
  }
94
94
  }
95
+ function formatObservabilityProgress(event) {
96
+ switch (event.type) {
97
+ case "runtime.observability": return `Runtime observed: ${event.name} - ${event.summary}`;
98
+ default: return null;
99
+ }
100
+ }
95
101
  function formatRuntimeResult(result) {
96
102
  const lines = [
97
103
  `Pipeline complete: ${result.outcome}`,
@@ -152,7 +158,7 @@ const BUILTIN_PIPE_COMMANDS = new Set([
152
158
  "runner-job"
153
159
  ]);
154
160
  function createCliProgram() {
155
- const configuredPipeline = tryLoadPipelineConfig(process.env.PIPELINE_TARGET_PATH ?? process.cwd(), { allowMissingLintFileReferences: true });
161
+ const configuredPipeline = tryLoadConfiguredEntrypoints(process.env.PIPELINE_TARGET_PATH ?? process.cwd());
156
162
  const program = new Command();
157
163
  program.name("@oisincoveney/pipeline").description("Run and install the oisin pipeline").exitOverride();
158
164
  const runAction = async (descriptionParts, flags) => {
@@ -191,11 +197,8 @@ function createCliProgram() {
191
197
  });
192
198
  program.command("install-commands").description("Install generated slash-command adapters into this repository").addOption(new Option("--host <host>", "host command set to install").choices([
193
199
  "all",
194
- "claude",
195
200
  "opencode",
196
- "codex",
197
- "kimi",
198
- "pi"
201
+ "codex"
199
202
  ]).default("all").argParser(parseCommandHost)).option("--dry-run", "show planned changes without writing files").option("--check", "fail if generated command files are missing or stale").option("--force", "overwrite manually edited command files").action(async (flags) => {
200
203
  const result = await installCommands({
201
204
  ...flags,
@@ -214,6 +217,14 @@ function createCliProgram() {
214
217
  } });
215
218
  return program;
216
219
  }
220
+ function tryLoadConfiguredEntrypoints(cwd) {
221
+ try {
222
+ return tryLoadPipelineConfig(cwd, { allowMissingLintFileReferences: true });
223
+ } catch (err) {
224
+ if (err instanceof PipelineConfigError) return null;
225
+ throw err;
226
+ }
227
+ }
217
228
  function registerConfiguredEntrypointCommands(program, config) {
218
229
  const registered = /* @__PURE__ */ new Set();
219
230
  if (!config) return registered;