@techgoblin/gobstack 0.5.0-beta.3 → 0.5.0-beta.4

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/bin/goblin-init CHANGED
@@ -636,8 +636,8 @@ fi
636
636
  CONFIG="$TARGET/.goblin/goblin.yaml"
637
637
  [ -f "$CONFIG" ] || { g_err "install wrote no .goblin/goblin.yaml at $TARGET"; exit 1; }
638
638
  if [ "$DRYRUN" -eq 0 ]; then
639
- sed -i "s|^branch:.*|branch: $BRANCH|" "$CONFIG" || { g_err "cannot write the declared branch into $CONFIG"; exit 1; }
640
- sed -i "s|^owner_email:.*|owner_email: $EMAIL|" "$CONFIG" || { g_err "cannot write the owner email into $CONFIG"; exit 1; }
639
+ g_sed_i "s|^branch:.*|branch: $BRANCH|" "$CONFIG" || { g_err "cannot write the declared branch into $CONFIG"; exit 1; }
640
+ g_sed_i "s|^owner_email:.*|owner_email: $EMAIL|" "$CONFIG" || { g_err "cannot write the owner email into $CONFIG"; exit 1; }
641
641
  TMP_CFG=$(mktemp) || { g_err "mktemp failed"; exit 2; }
642
642
  GATE_SUB=$(mktemp) || { g_err "mktemp failed"; exit 2; }
643
643
  # print the gate body once, read it as data: an & or / inside the command must not
@@ -241,7 +241,7 @@ if [ "$RE_PIN" -eq 1 ]; then
241
241
  fi
242
242
  # One line, in place. Every other line of the config - comments included - is untouched, so
243
243
  # the `owned` contract holds for everything except the single value just asked for.
244
- sed -i "s|^practice_sha256:.*|practice_sha256: $NEW_SHA|" "$CONFIG" \
244
+ g_sed_i "s|^practice_sha256:.*|practice_sha256: $NEW_SHA|" "$CONFIG" \
245
245
  || { g_err "could not rewrite the pin in $CONFIG"; exit 1; }
246
246
  # Fail closed: never report a re-pin that did not land. The failure this command exists to
247
247
  # remove is a hash nobody verified (measured at bf7e9c9: sed -i could not write to a read-only
@@ -793,7 +793,7 @@ if [ "$DRY_RUN" -eq 0 ]; then
793
793
  cur=$(g_yaml_scalar "$CONFIG" disabled)
794
794
  cur=${cur#[}; cur=${cur%]}
795
795
  new=$(printf '%s,%s' "$cur" "$p" | tr ',' '\n' | grep -v '^$' | sort -u | paste -sd, -)
796
- sed -i "s|^disabled:.*|disabled: [$new]|" "$CONFIG"
796
+ g_sed_i "s|^disabled:.*|disabled: [$new]|" "$CONFIG"
797
797
  fi
798
798
  done
799
799
  g_info "recorded opt-out: $OPT_OUT"
package/bin/goblin-lib.sh CHANGED
@@ -274,6 +274,21 @@ g_installed_scalar_options() {
274
274
  ' "$1"
275
275
  }
276
276
 
277
+ # g_sed_i <sed-script> <file...> — in-place sed that works on BOTH sed families.
278
+ # GNU sed takes -i with an optional suffix attached; BSD sed (macOS) REQUIRES an argument
279
+ # after -i (the backup suffix), so a bare `sed -i 's|…|…|' file` makes BSD read the script
280
+ # as the suffix and the file as the program — the client's `sed: 1: "...": command a
281
+ # expects \ followed by text` (Mac, 2026-10-06). The empty-suffix form `-i ''` is a syntax
282
+ # error on GNU, hence the branch. Callers: g_sed_i 's|a|b|' file
283
+ g_sed_i() {
284
+ local script="$1"; shift
285
+ if sed --version >/dev/null 2>&1; then
286
+ sed -i "$script" "$@"
287
+ else
288
+ sed -i '' "$script" "$@"
289
+ fi
290
+ }
291
+
277
292
  # ------------------------------------------------------------- self-test -----
278
293
  # Proves the parser actually parses. Every assertion is a real comparison against a
279
294
  # value written to a temp file in this function — blank the awk in g_yaml_scalar and
@@ -36,6 +36,14 @@ usage() { sed -n '2,/^$/p' "${BASH_SOURCE[0]}" | sed 's/^# \{0,1\}//'; }
36
36
 
37
37
  g_err() { printf 'error: %s\n' "$*" >&2; }
38
38
 
39
+ # g_sed_i <sed-script> <file...> — in-place sed on BOTH sed families (goblin-lib's
40
+ # helper; duplicated here because this command is deliberately self-contained and
41
+ # does not source goblin-lib.sh — the BSD sed bomb, client Mac 2026-10-06).
42
+ g_sed_i() {
43
+ local script="$1"; shift
44
+ if sed --version >/dev/null 2>&1; then sed -i "$script" "$@"; else sed -i '' "$script" "$@"; fi
45
+ }
46
+
39
47
  # g_expand_tilde <path> — ~ and ~/... to $HOME (the goblin-install:81 idiom).
40
48
  g_expand_tilde() {
41
49
  case "$1" in
@@ -403,7 +411,7 @@ else
403
411
  g_err "upgrade: $CONFIG has neither an active nor a commented engine_dir: line - not a 0.4.4 template; aborting"
404
412
  exit 2
405
413
  fi
406
- sed -i "s|^# engine_dir:.*|$(active_engine_line | sed 's/[&|]/\\&/g')|" "$CONFIG"
414
+ g_sed_i "s|^# engine_dir:.*|$(active_engine_line | sed 's/[&|]/\\&/g')|" "$CONFIG"
407
415
  fi
408
416
 
409
417
  # ---- installed.json: engine block + drop exactly the 18 engine entries ----
@@ -476,7 +484,7 @@ if [ -f "$WF" ] && grep -q 'run: bash .goblin/bin/goblin-verify' "$WF"; then
476
484
  # a files-RECORDED artifact, so this rewrite re-hashes its record entry here,
477
485
  # in the same commit (IN-02 hashes every recorded file; a rewritten artifact
478
486
  # with a stale recorded hash would fail verify #2 — measured this session).
479
- sed -i "s|run: bash .goblin/bin/goblin-verify|run: npx @techgoblin/gobstack@$CLI_VERSION run goblin-verify|" "$WF"
487
+ g_sed_i "s|run: bash .goblin/bin/goblin-verify|run: npx @techgoblin/gobstack@$CLI_VERSION run goblin-verify|" "$WF"
480
488
  WF_NEW=$(sha256 "$WF")
481
489
  python3 "$PYJ/rehash_record.py" "$INSTALLED" ".github/workflows/goblin-gate.yml" "$WF_NEW" || {
482
490
  g_err "upgrade: re-hashing the rewritten workflow in $INSTALLED failed - the tree is uncommitted; fix: git checkout ."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techgoblin/gobstack",
3
- "version": "0.5.0-beta.3",
3
+ "version": "0.5.0-beta.4",
4
4
  "description": "Agent-discipline toolkit: one verify command, an enforcement matrix, and LIMITS. bash engine, npm shim.",
5
5
  "bin": {
6
6
  "goblin": "bin/goblin.js",