@sweny-ai/core 0.1.105 → 0.1.106

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 (2) hide show
  1. package/dist/executor.js +37 -5
  2. package/package.json +1 -1
package/dist/executor.js CHANGED
@@ -625,18 +625,50 @@ function resolveSkillInstructions(skillIds, skills) {
625
625
  * `options.env ?? process.env` so an explicit env map is honored consistently
626
626
  * with Source resolution (which reads the same map). Defaults to
627
627
  * `process.env` when omitted.
628
+ *
629
+ * Presence vs. truthiness: an explicitly-provided empty string is treated as
630
+ * present, not absent. Resolution rules:
631
+ * - An override that is present (any string, including "") wins; the env
632
+ * var is not consulted. An explicit "" override does NOT silently fall
633
+ * through to env.
634
+ * - Otherwise the env var (when declared) is used.
635
+ * - A value that is `undefined` (no override, no env var) is absent: a
636
+ * required field reports "not provided".
637
+ * - A value that is "" is present-but-empty: a required field reports a
638
+ * distinct "set to empty" message (you set it, but to an unusable value),
639
+ * while an optional field passes the empty string through.
628
640
  */
629
641
  function resolveConfig(skills, overrides, env = process.env) {
630
642
  const config = {};
631
643
  const missing = [];
632
644
  for (const skill of skills.values()) {
633
645
  for (const [key, field] of Object.entries(skill.config)) {
634
- const value = overrides?.[key] ?? (field.env ? env[field.env] : undefined);
635
- if (value) {
636
- config[key] = value;
646
+ // Explicit override wins, including an empty string — `in` distinguishes
647
+ // a present "" from an absent key, so an override never falls through to
648
+ // env in a surprising way.
649
+ const hasOverride = overrides != null && key in overrides;
650
+ const value = hasOverride ? overrides[key] : field.env ? env[field.env] : undefined;
651
+ const source = field.env ? ` (env: ${field.env})` : "";
652
+ const label = `${skill.id}.${key}${source || " (env: none)"}`;
653
+ if (value === undefined) {
654
+ // Truly absent: no override and no env value.
655
+ if (field.required) {
656
+ missing.push(`${label}: not provided`);
657
+ }
658
+ }
659
+ else if (value === "") {
660
+ // Present but empty. An empty credential is unusable for a required
661
+ // field; surface a distinct message so the user can tell "set to empty"
662
+ // from "forgot it". Optional empty values pass through unchanged.
663
+ if (field.required) {
664
+ missing.push(`${label}: set to empty`);
665
+ }
666
+ else {
667
+ config[key] = value;
668
+ }
637
669
  }
638
- else if (field.required) {
639
- missing.push(`${skill.id}.${key} (env: ${field.env ?? "none"})`);
670
+ else {
671
+ config[key] = value;
640
672
  }
641
673
  }
642
674
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sweny-ai/core",
3
- "version": "0.1.105",
3
+ "version": "0.1.106",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sweny": "./dist/cli/main.js"