@sweny-ai/core 0.1.77 → 0.1.78

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 (119) hide show
  1. package/dist/browser.d.ts +11 -5
  2. package/dist/browser.js +11 -11
  3. package/dist/claude.d.ts +16 -0
  4. package/dist/claude.js +98 -9
  5. package/dist/cli/config.d.ts +22 -0
  6. package/dist/cli/config.js +56 -9
  7. package/dist/cli/main.d.ts +1 -1
  8. package/dist/cli/main.js +56 -57
  9. package/dist/cli/marketplace.js +35 -9
  10. package/dist/cli/publish.d.ts +10 -0
  11. package/dist/cli/publish.js +22 -14
  12. package/dist/loader.d.ts +40 -0
  13. package/dist/loader.js +73 -0
  14. package/dist/mcp-catalog.d.ts +47 -0
  15. package/dist/mcp-catalog.js +304 -0
  16. package/dist/mcp.d.ts +6 -9
  17. package/dist/mcp.js +24 -314
  18. package/dist/schema.d.ts +183 -151
  19. package/dist/schema.js +49 -7
  20. package/dist/skills/custom-loader.d.ts +40 -0
  21. package/dist/skills/custom-loader.js +107 -32
  22. package/dist/skills/index.d.ts +13 -1
  23. package/dist/skills/index.js +12 -3
  24. package/dist/studio.js +4 -1
  25. package/dist/templates.d.ts +29 -8
  26. package/dist/templates.js +30 -20
  27. package/dist/types.d.ts +12 -0
  28. package/dist/verify.js +42 -4
  29. package/package.json +8 -4
  30. package/dist/__tests__/cascade.test.d.ts +0 -11
  31. package/dist/__tests__/cascade.test.js +0 -452
  32. package/dist/__tests__/claude.test.d.ts +0 -1
  33. package/dist/__tests__/claude.test.js +0 -427
  34. package/dist/__tests__/custom-loader.test.d.ts +0 -1
  35. package/dist/__tests__/custom-loader.test.js +0 -116
  36. package/dist/__tests__/executor.test.d.ts +0 -1
  37. package/dist/__tests__/executor.test.js +0 -1635
  38. package/dist/__tests__/integration/datadog.integration.test.d.ts +0 -1
  39. package/dist/__tests__/integration/datadog.integration.test.js +0 -23
  40. package/dist/__tests__/integration/e2e-workflow.integration.test.d.ts +0 -1
  41. package/dist/__tests__/integration/e2e-workflow.integration.test.js +0 -75
  42. package/dist/__tests__/integration/github.integration.test.d.ts +0 -1
  43. package/dist/__tests__/integration/github.integration.test.js +0 -37
  44. package/dist/__tests__/integration/harness.d.ts +0 -24
  45. package/dist/__tests__/integration/harness.js +0 -34
  46. package/dist/__tests__/integration/linear.integration.test.d.ts +0 -1
  47. package/dist/__tests__/integration/linear.integration.test.js +0 -15
  48. package/dist/__tests__/integration/sentry.integration.test.d.ts +0 -1
  49. package/dist/__tests__/integration/sentry.integration.test.js +0 -20
  50. package/dist/__tests__/integration/slack.integration.test.d.ts +0 -1
  51. package/dist/__tests__/integration/slack.integration.test.js +0 -22
  52. package/dist/__tests__/integration/sources.integration.test.d.ts +0 -1
  53. package/dist/__tests__/integration/sources.integration.test.js +0 -123
  54. package/dist/__tests__/publish.test.d.ts +0 -1
  55. package/dist/__tests__/publish.test.js +0 -180
  56. package/dist/__tests__/requires.test.d.ts +0 -1
  57. package/dist/__tests__/requires.test.js +0 -82
  58. package/dist/__tests__/retry.test.d.ts +0 -1
  59. package/dist/__tests__/retry.test.js +0 -213
  60. package/dist/__tests__/schema.test.d.ts +0 -1
  61. package/dist/__tests__/schema.test.js +0 -600
  62. package/dist/__tests__/skill-config-integration.test.d.ts +0 -1
  63. package/dist/__tests__/skill-config-integration.test.js +0 -204
  64. package/dist/__tests__/skills-index.test.d.ts +0 -1
  65. package/dist/__tests__/skills-index.test.js +0 -119
  66. package/dist/__tests__/skills.test.d.ts +0 -1
  67. package/dist/__tests__/skills.test.js +0 -565
  68. package/dist/__tests__/spec-conformance.test.d.ts +0 -18
  69. package/dist/__tests__/spec-conformance.test.js +0 -1084
  70. package/dist/__tests__/studio.test.d.ts +0 -1
  71. package/dist/__tests__/studio.test.js +0 -403
  72. package/dist/__tests__/templates.test.d.ts +0 -1
  73. package/dist/__tests__/templates.test.js +0 -49
  74. package/dist/__tests__/testing.test.d.ts +0 -1
  75. package/dist/__tests__/testing.test.js +0 -242
  76. package/dist/__tests__/verify.test.d.ts +0 -1
  77. package/dist/__tests__/verify.test.js +0 -517
  78. package/dist/__tests__/version-consistency.test.d.ts +0 -1
  79. package/dist/__tests__/version-consistency.test.js +0 -312
  80. package/dist/__tests__/workflow-builder.test.d.ts +0 -1
  81. package/dist/__tests__/workflow-builder.test.js +0 -110
  82. package/dist/__tests__/workflow-yaml.test.d.ts +0 -1
  83. package/dist/__tests__/workflow-yaml.test.js +0 -201
  84. package/dist/cli/__tests__/diagram.test.d.ts +0 -1
  85. package/dist/cli/__tests__/diagram.test.js +0 -225
  86. package/dist/cli/__tests__/report-cloud.test.d.ts +0 -1
  87. package/dist/cli/__tests__/report-cloud.test.js +0 -165
  88. package/dist/cli/__tests__/upgrade.test.d.ts +0 -1
  89. package/dist/cli/__tests__/upgrade.test.js +0 -317
  90. package/dist/cli/__tests__/version-check.test.d.ts +0 -1
  91. package/dist/cli/__tests__/version-check.test.js +0 -209
  92. package/dist/cli/config.test.d.ts +0 -1
  93. package/dist/cli/config.test.js +0 -200
  94. package/dist/cli/credentials.test.d.ts +0 -1
  95. package/dist/cli/credentials.test.js +0 -172
  96. package/dist/cli/e2e.test.d.ts +0 -1
  97. package/dist/cli/e2e.test.js +0 -690
  98. package/dist/cli/marketplace.test.d.ts +0 -1
  99. package/dist/cli/marketplace.test.js +0 -355
  100. package/dist/cli/new.test.d.ts +0 -1
  101. package/dist/cli/new.test.js +0 -1043
  102. package/dist/cli/output.test.d.ts +0 -1
  103. package/dist/cli/output.test.js +0 -180
  104. package/dist/cli/publish.test.d.ts +0 -1
  105. package/dist/cli/publish.test.js +0 -610
  106. package/dist/cli/renderer.test.d.ts +0 -1
  107. package/dist/cli/renderer.test.js +0 -302
  108. package/dist/executor.test.d.ts +0 -1
  109. package/dist/executor.test.js +0 -618
  110. package/dist/mcp.test.d.ts +0 -1
  111. package/dist/mcp.test.js +0 -735
  112. package/dist/mermaid.test.d.ts +0 -1
  113. package/dist/mermaid.test.js +0 -256
  114. package/dist/sources.test.d.ts +0 -1
  115. package/dist/sources.test.js +0 -265
  116. package/dist/sources.validation.test.d.ts +0 -12
  117. package/dist/sources.validation.test.js +0 -380
  118. package/dist/workflow-builder.test.d.ts +0 -1
  119. package/dist/workflow-builder.test.js +0 -123
package/dist/templates.js CHANGED
@@ -1,13 +1,15 @@
1
1
  /**
2
- * Template loading for issues and PRs.
2
+ * Template + rules/context loading for the CLI.
3
3
  *
4
- * Templates can come from:
4
+ * Templates and additional-context documents can come from:
5
5
  * 1. Local file path (relative to repo root)
6
6
  * 2. URL (fetched at runtime)
7
- * 3. Built-in defaults
7
+ * 3. Built-in defaults / inline text
8
8
  *
9
- * Delegates to sources.ts for actual resolution; this module provides
10
- * backwards-compatible wrappers with fallback semantics.
9
+ * Delegates to source-resolver.ts for the actual fetch. Fix #16: both
10
+ * `loadTemplate` and `loadAdditionalContext` now honor `offline` and
11
+ * `fetchAuth` the same way the executor's per-node Sources do, so CLI-level
12
+ * rules/context stay consistent with everything the executor touches later.
11
13
  */
12
14
  import * as path from "node:path";
13
15
  import { classifySource } from "./sources.js";
@@ -50,39 +52,43 @@ export const DEFAULT_PR_TEMPLATE = `## Summary
50
52
  ## Related Issues
51
53
  Fixes #
52
54
  `;
53
- /** Default resolution context used by template helpers. */
54
- function defaultCtx(cwd) {
55
+ function buildCtx(options) {
55
56
  return {
56
- cwd,
57
- env: process.env,
58
- authConfig: {},
59
- offline: false,
57
+ cwd: options.cwd ?? process.cwd(),
58
+ env: options.env ?? process.env,
59
+ authConfig: options.fetchAuth ?? {},
60
+ offline: options.offline ?? false,
60
61
  logger: consoleLogger,
61
62
  };
62
63
  }
63
64
  /**
64
65
  * Load a template from a file path or URL.
65
66
  * Returns the default if source is empty or loading fails.
67
+ *
68
+ * Accepts the legacy `cwd?: string` signature for backward compat.
66
69
  */
67
- export async function loadTemplate(source, fallback, cwd = process.cwd()) {
70
+ export async function loadTemplate(source, fallback, options = {}) {
68
71
  if (!source || source.trim() === "")
69
72
  return fallback;
73
+ const opts = typeof options === "string" ? { cwd: options } : options;
70
74
  try {
71
- const resolved = await resolveSource(source.trim(), "template", defaultCtx(cwd));
75
+ const resolved = await resolveSource(source.trim(), "template", buildCtx(opts));
72
76
  return resolved.content;
73
77
  }
74
78
  catch (err) {
75
- console.warn(`[templates] Failed to load template: ${err.message}, using default`);
79
+ const msg = err instanceof Error ? err.message : String(err);
80
+ console.warn(`[templates] Failed to load template: ${msg}, using default`);
76
81
  return fallback;
77
82
  }
78
83
  }
79
84
  /**
80
85
  * Resolve issue and PR templates from config.
81
86
  */
82
- export async function resolveTemplates(config, cwd) {
87
+ export async function resolveTemplates(config, options = {}) {
88
+ const opts = typeof options === "string" ? { cwd: options } : options;
83
89
  const [issueTemplate, prTemplate] = await Promise.all([
84
- loadTemplate(config.issueTemplate, DEFAULT_ISSUE_TEMPLATE, cwd),
85
- loadTemplate(config.prTemplate, DEFAULT_PR_TEMPLATE, cwd),
90
+ loadTemplate(config.issueTemplate, DEFAULT_ISSUE_TEMPLATE, opts),
91
+ loadTemplate(config.prTemplate, DEFAULT_PR_TEMPLATE, opts),
86
92
  ]);
87
93
  return { issueTemplate, prTemplate };
88
94
  }
@@ -91,12 +97,15 @@ export async function resolveTemplates(config, cwd) {
91
97
  * Each source is resolved eagerly (including URLs) and wrapped with a header.
92
98
  * Returns { resolved, urls } — resolved text for all sources; urls is kept
93
99
  * for API compat but will be empty since URLs now resolve eagerly.
100
+ *
101
+ * Accepts the legacy `cwd?: string` signature for backward compat.
94
102
  */
95
- export async function loadAdditionalContext(sources, cwd = process.cwd()) {
103
+ export async function loadAdditionalContext(sources, options = {}) {
96
104
  if (sources.length === 0)
97
105
  return { resolved: "", urls: [] };
106
+ const opts = typeof options === "string" ? { cwd: options } : options;
98
107
  const parts = [];
99
- const ctx = defaultCtx(cwd);
108
+ const ctx = buildCtx(opts);
100
109
  for (const source of sources) {
101
110
  const trimmed = source.trim();
102
111
  if (!trimmed)
@@ -114,7 +123,8 @@ export async function loadAdditionalContext(sources, cwd = process.cwd()) {
114
123
  }
115
124
  }
116
125
  catch (err) {
117
- console.warn(`[templates] Failed to load context source: ${err.message}`);
126
+ const msg = err instanceof Error ? err.message : String(err);
127
+ console.warn(`[templates] Failed to load context source: ${msg}`);
118
128
  }
119
129
  }
120
130
  }
package/dist/types.d.ts CHANGED
@@ -201,6 +201,18 @@ export interface ToolCall {
201
201
  tool: string;
202
202
  input: unknown;
203
203
  output?: unknown;
204
+ /**
205
+ * Authoritative outcome of the tool invocation.
206
+ *
207
+ * When present, this is the source of truth for `verify` checks — the
208
+ * output-shape heuristic is a legacy fallback only. Set by the Claude
209
+ * runtime on tool completion: "success" when the tool returned normally,
210
+ * "error" when it threw or the MCP server returned is_error=true.
211
+ *
212
+ * Absent status indicates a legacy or hand-constructed ToolCall — verify
213
+ * falls back to inspecting `output` for an `error` key.
214
+ */
215
+ status?: "success" | "error";
204
216
  }
205
217
  export type ExecutionEvent = {
206
218
  type: "workflow:start";
package/dist/verify.js CHANGED
@@ -69,19 +69,35 @@ export function resolvePath(data, path) {
69
69
  }
70
70
  return { ok: true, mode: parsed.mode, values: current };
71
71
  }
72
- // A tool call "succeeded" when its output does not carry a non-null `error` field.
73
- // `{ error: null }` and `{ error: false }` are treated as success — many real
74
- // tools include the key with a null sentinel.
72
+ // Legacy output-shape heuristic: a tool call "succeeded" when its output
73
+ // does not carry a non-null `error` field. Kept as a fallback for ToolCall
74
+ // records that predate the explicit `status` field (hand-constructed in
75
+ // tests, older runtimes). The Claude runtime now sets `status` directly.
75
76
  export function isErrorOutput(output) {
76
77
  if (!output || typeof output !== "object")
77
78
  return false;
78
79
  const err = output.error;
79
80
  return err !== undefined && err !== null && err !== false;
80
81
  }
82
+ /**
83
+ * A tool call is considered successful when:
84
+ * - explicit `status === "success"`, OR
85
+ * - no explicit status AND output does not look like an error.
86
+ *
87
+ * `status` is authoritative. It's the only signal we have for external MCP
88
+ * tools whose structured output isn't exposed to the workflow runtime.
89
+ */
90
+ function didSucceed(c) {
91
+ if (c.status === "error")
92
+ return false;
93
+ if (c.status === "success")
94
+ return true;
95
+ return !isErrorOutput(c.output);
96
+ }
81
97
  function succeededTools(toolCalls) {
82
98
  const names = new Set();
83
99
  for (const c of toolCalls) {
84
- if (!isErrorOutput(c.output))
100
+ if (didSucceed(c))
85
101
  names.add(c.tool);
86
102
  }
87
103
  return names;
@@ -180,8 +196,30 @@ export function checkOutputRequired(paths, data) {
180
196
  return null;
181
197
  return `output_required: ${failures.join("; ")}`;
182
198
  }
199
+ /**
200
+ * Cap on `verify.output_matches[].matches` source length.
201
+ *
202
+ * `matches` is user-supplied through workflow YAML, including marketplace
203
+ * workflows. A pathological pattern like `(a+)+$` causes exponential
204
+ * backtracking in V8's regex engine. Capping the source length is a cheap,
205
+ * useful defense — well-formed verify regexes are tens of characters at
206
+ * most. Patterns longer than this are almost always either generated junk
207
+ * or a deliberate ReDoS attempt; either way, refusing to compile is safer
208
+ * than executing them.
209
+ *
210
+ * Caveat: length alone does NOT prevent all ReDoS — a 12-char pattern like
211
+ * `(a+)+$` is still catastrophic against the right input. Future work:
212
+ * gate compilation through `safe-regex` or use the `re2` engine for
213
+ * marketplace inputs. The cap closes the obvious abuse surface without
214
+ * adding a runtime dep right now.
215
+ */
216
+ const MAX_REGEX_SOURCE_LENGTH = 1000;
183
217
  function compileMatch(m) {
184
218
  if (m.matches !== undefined) {
219
+ if (m.matches.length > MAX_REGEX_SOURCE_LENGTH) {
220
+ throw new Error(`regex source exceeds ${MAX_REGEX_SOURCE_LENGTH} characters (got ${m.matches.length}); ` +
221
+ `tighten the pattern to avoid catastrophic-backtracking risk`);
222
+ }
185
223
  // Throws synchronously if the regex source is invalid; surfaced as a
186
224
  // verify failure rather than a crash because the executor catches.
187
225
  return { match: m, regex: new RegExp(m.matches) };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sweny-ai/core",
3
- "version": "0.1.77",
3
+ "version": "0.1.78",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sweny": "./dist/cli/main.js"
@@ -46,10 +46,11 @@
46
46
  "dist"
47
47
  ],
48
48
  "scripts": {
49
- "build": "rm -rf dist && tsc && cp src/workflows/*.yml dist/workflows/ && node scripts/build-workflow-browser.mjs",
49
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && cp src/workflows/*.yml dist/workflows/ && node scripts/build-workflow-browser.mjs && node scripts/write-public-schema.mjs",
50
50
  "typecheck": "tsc --noEmit",
51
- "test": "vitest run --exclude 'src/__tests__/integration/**'",
52
- "test:integration": "vitest run --config vitest.integration.config.ts"
51
+ "test": "vitest run --exclude 'src/__tests__/integration/**' --exclude 'dist/**'",
52
+ "test:integration": "vitest run --config vitest.integration.config.ts",
53
+ "check:schema-drift": "node scripts/write-public-schema.mjs && git diff --exit-code -- ../../spec/public/schemas/workflow.json"
53
54
  },
54
55
  "dependencies": {
55
56
  "@anthropic-ai/claude-agent-sdk": "^0.2.114",
@@ -61,6 +62,9 @@
61
62
  },
62
63
  "devDependencies": {
63
64
  "@anthropic-ai/claude-code": "^2.1.114",
65
+ "ajv": "^8.18.0",
66
+ "esbuild": "^0.28.0",
67
+ "prettier": "^3.8.3",
64
68
  "vitest": "^4.1.4"
65
69
  },
66
70
  "publishConfig": {
@@ -1,11 +0,0 @@
1
- /**
2
- * Rules / Context Cascade + max_turns Tests
3
- *
4
- * Covers the spec sections:
5
- * - Workflow > Rules & Context
6
- * - Workflow > Runtime Input (rules/context)
7
- * - Nodes > Max Turns Semantics
8
- * - Nodes > Rules & Context (cascade + `only` flag)
9
- * - Nodes > Input Augmentation (assembly order)
10
- */
11
- export {};