@sigilagent/sigil 0.0.0-stage → 0.6.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 (4) hide show
  1. package/README.md +47 -2
  2. package/bin/sigil +49 -0
  3. package/install.sh +229 -0
  4. package/package.json +34 -4
package/README.md CHANGED
@@ -1,3 +1,48 @@
1
- # Temporary Holding Version
1
+ # Sigil
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **The skill compiler.** Sigil compiles a `SKILL.md` through a typed AG-IR into a
4
+ runnable agent harness, so any model (small and local included) follows the skill
5
+ by construction. Don't prompt the skill — compile it.
6
+
7
+ ```bash
8
+ npm install -g @sigilagent/sigil
9
+ ```
10
+
11
+ ```bash
12
+ sigil compile ./SKILL.md -e agent.jac # the compiler, end to end
13
+ sigil solve "turn report.pdf into clean CSV" # the agent: compile on miss, reuse on hit
14
+ sigil library # the compiled skills, with run stats
15
+ sigil chat # the conversational agent over the same graph
16
+ ```
17
+
18
+ Docs: [sigilagent.com](https://sigilagent.com) · [github.com/sigilagent/sigil](https://github.com/sigilagent/sigil)
19
+
20
+ ## What this package installs
21
+
22
+ Sigil runs on the native [jac](https://www.jac-lang.org) runtime, not on Node. This
23
+ package is a thin launcher: the first time you run `sigil` (and after each
24
+ `npm update`), it runs the release's own installer, which
25
+
26
+ 1. installs the jac version this release is pinned to into `~/.local/bin`, if you don't have it,
27
+ 2. fetches the matching Sigil release into `~/.sigil/app`,
28
+ 3. provisions its runtime dependencies (the LLM backend, the chat REPL).
29
+
30
+ Your agent's graph lives in `~/.sigil/app`, outside `node_modules`, so upgrading or
31
+ reinstalling the npm package never touches it. Nothing needs root.
32
+
33
+ Requires macOS or Linux with `bash`, `curl` and `git`. The same install is also
34
+ available without npm:
35
+
36
+ ```bash
37
+ curl -fsSL https://github.com/sigilagent/sigil/releases/latest/download/install.sh | bash
38
+ ```
39
+
40
+ ## Updating and removing
41
+
42
+ ```bash
43
+ npm update -g @sigilagent/sigil # the next `sigil` run upgrades ~/.sigil/app
44
+ npm uninstall -g @sigilagent/sigil
45
+ rm -rf ~/.sigil # also delete the agent, its graph and compiled skills
46
+ ```
47
+
48
+ `SIGIL_HOME` moves Sigil's state directory (default `~/.sigil`; the app is `$SIGIL_HOME/app`).
package/bin/sigil ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bash
2
+ # sigil — the npm entry point (`npm i -g @sigilagent/sigil`, or `npx @sigilagent/sigil`).
3
+ #
4
+ # Sigil does not run out of node_modules. It lives where the curl installer puts
5
+ # it, ~/.sigil/app, because the graph is keyed to the app's path: run it from the
6
+ # package directory and every `npm update` would replace the agent with an empty
7
+ # one. So this script only makes sure ~/.sigil/app is at least this package's
8
+ # version — running the install.sh shipped beside it, pinned to the matching
9
+ # tag, when it is not — and then hands over to the real launcher.
10
+ #
11
+ # It only ever upgrades. A tree already newer than the package (`sigil update`,
12
+ # a curl install) is left exactly as it is.
13
+ #
14
+ # SIGIL_HOME is the STATE dir here, as it is everywhere in the runtime
15
+ # (default ~/.sigil). The app is $SIGIL_HOME/app. install.sh calls the app dir
16
+ # SIGIL_HOME, so that meaning is handed to it alone and never exported.
17
+ set -euo pipefail
18
+
19
+ STATE="${SIGIL_HOME:-$HOME/.sigil}"
20
+ APP="$STATE/app"
21
+ BIN="$STATE/bin" # install.sh's launcher shim lands here, off PATH: npm owns `sigil`
22
+
23
+ # npm links bin/sigil into a bin dir on PATH; find the package behind the link.
24
+ src="${BASH_SOURCE[0]}"
25
+ while [ -L "$src" ]; do
26
+ dir="$(cd -P "$(dirname "$src")" && pwd)"
27
+ src="$(readlink "$src")"
28
+ case "$src" in /*) ;; *) src="$dir/$src" ;; esac
29
+ done
30
+ PKG="$(cd -P "$(dirname "$src")/.." && pwd)"
31
+
32
+ want="$(sed -n 's/^ *"version": *"\([^"]*\)".*/\1/p' "$PKG/package.json" | head -1)"
33
+ have="$(sed -n 's/^version *= *"\([^"]*\)".*/\1/p' "$APP/jac.toml" 2>/dev/null | head -1 || true)"
34
+ newest="$(printf '%s\n%s\n' "$have" "$want" | sort -V | tail -1)"
35
+
36
+ # Exported, so `sigil update` (which re-runs the latest release's install.sh)
37
+ # refreshes this launcher too instead of planting a second one in ~/.local/bin.
38
+ export SIGIL_BIN_DIR="$BIN" SIGIL_PATH_CHECK=0
39
+
40
+ if [ -z "$have" ] || { [ "$have" != "$want" ] && [ "$newest" = "$want" ]; }; then
41
+ # stdout belongs to the command the user typed: `sigil soul | jq` on a first
42
+ # run must not get the installer's banner.
43
+ SIGIL_HOME="$APP" SIGIL_REF="v$want" bash "$PKG/install.sh" >&2
44
+ fi
45
+
46
+ # install.sh's shim pins the jac it verified (SIGIL_JAC). A tree that was
47
+ # installed some other way has no shim here; its own launcher checks jac itself.
48
+ [ -x "$BIN/sigil" ] && exec "$BIN/sigil" "$@"
49
+ exec "$APP/sigil" "$@"
package/install.sh ADDED
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Sigil installer — https://sigilagent.com
4
+ #
5
+ # curl -fsSL https://github.com/sigilagent/sigil/releases/latest/download/install.sh | bash
6
+ #
7
+ # What it does:
8
+ # 1. fetches the Sigil source into ~/.sigil/app (override with $SIGIL_HOME)
9
+ # 2. makes sure the jac it runs on is the version it pins (jac.toml `jac-version`),
10
+ # installing that native `jac` binary into ~/.local/bin if yours differs
11
+ # 3. provisions the runtime deps (PyYAML + the LLM runtime) into the project
12
+ # 4. drops a `sigil` launcher onto your PATH (~/.local/bin, override $SIGIL_BIN_DIR)
13
+ #
14
+ # Nothing here needs root. Re-running is safe: it updates an existing install.
15
+ #
16
+ # Env knobs:
17
+ # SIGIL_HOME where the source lives (default: ~/.sigil/app)
18
+ # SIGIL_BIN_DIR where the launcher goes (default: ~/.local/bin)
19
+ # SIGIL_PATH_CHECK=0 don't ask for SIGIL_BIN_DIR on PATH (the npm package
20
+ # puts its own `sigil` there and keeps this shim private)
21
+ # SIGIL_REF branch / tag / commit (default: main in the repo copy;
22
+ # a release asset is rewritten to pin its own tag — see below)
23
+ # JAC_VERSION the jac to install (default: the fetched tree's pin)
24
+
25
+ set -euo pipefail
26
+
27
+ REPO="sigilagent/sigil"
28
+ SIGIL_HOME="${SIGIL_HOME:-$HOME/.sigil/app}"
29
+ BIN_DIR="${SIGIL_BIN_DIR:-$HOME/.local/bin}"
30
+ # Self-pinning releases: the release workflow rewrites DEFAULT_REF to the tag in
31
+ # the copy it attaches to a GitHub Release, so `releases/latest/download/install.sh`
32
+ # installs exactly the released commit — not whatever main happens to be. The repo
33
+ # copy stays on main. SIGIL_REF always overrides either.
34
+ DEFAULT_REF="v0.6.1"
35
+ REF="${SIGIL_REF:-$DEFAULT_REF}"
36
+ # The PATH you came in with: installing jac below prepends ~/.local/bin for this
37
+ # script only, and the closing PATH advice has to describe your shell, not ours.
38
+ ORIG_PATH="$PATH"
39
+
40
+ # ---- pretty output -----------------------------------------------------------
41
+ if [ -t 1 ]; then
42
+ P=$'\033[1;35m'; Y=$'\033[1;33m'; R=$'\033[1;31m'; G=$'\033[1;32m'; D=$'\033[0m'
43
+ else
44
+ P=""; Y=""; R=""; G=""; D=""
45
+ fi
46
+ info() { printf '%s::%s %s\n' "$P" "$D" "$*"; }
47
+ warn() { printf '%s!!%s %s\n' "$Y" "$D" "$*" >&2; }
48
+ die() { printf '%sxx%s %s\n' "$R" "$D" "$*" >&2; exit 1; }
49
+ have() { command -v "$1" >/dev/null 2>&1; }
50
+
51
+ printf '\n%s ◆ Sigil installer%s\n\n' "$P" "$D"
52
+
53
+ # ---- 1. fetch Sigil source ---------------------------------------------------
54
+ info "Fetching Sigil ($REF) → $SIGIL_HOME"
55
+ mkdir -p "$(dirname "$SIGIL_HOME")"
56
+ if have git; then
57
+ if [ -d "$SIGIL_HOME/.git" ]; then
58
+ # Upgrade in place. Two traps, both of which used to fail SILENTLY and leave
59
+ # the previous version installed under a "✓ Sigil installed" banner:
60
+ # * `checkout FETCH_HEAD` refuses whenever a tracked file has drifted, and
61
+ # a long-lived install drifts (a half-applied earlier upgrade is enough);
62
+ # * the fallback reset to `origin/$REF` names a ref that a tag fetch never
63
+ # creates — `fetch --depth 1 origin <tag>` writes FETCH_HEAD and nothing
64
+ # else, so `origin/v0.3.0` does not resolve.
65
+ # Reset to the commit we actually fetched, and let a failure be loud. This
66
+ # rewrites TRACKED files only: the graph in .jac/data, compiled skills and
67
+ # every other untracked/ignored file are left exactly where they are.
68
+ git -C "$SIGIL_HOME" fetch --depth 1 origin "$REF" \
69
+ || die "could not fetch '$REF' into $SIGIL_HOME."
70
+ git -C "$SIGIL_HOME" reset --hard -q FETCH_HEAD \
71
+ || die "could not update $SIGIL_HOME to '$REF' (local changes to tracked files?)."
72
+ # An install that reports success while running last month's code is the one
73
+ # outcome worth an explicit check.
74
+ at="$(git -C "$SIGIL_HOME" rev-parse HEAD 2>/dev/null || echo unknown)"
75
+ want="$(git -C "$SIGIL_HOME" rev-parse FETCH_HEAD 2>/dev/null || echo unknown)"
76
+ [ "$at" = "$want" ] || die "update did not take: $SIGIL_HOME is at $at, expected $want."
77
+ else
78
+ rm -rf "$SIGIL_HOME"
79
+ git clone --depth 1 --branch "$REF" "https://github.com/$REPO.git" "$SIGIL_HOME" 2>/dev/null \
80
+ || git clone --depth 1 "https://github.com/$REPO.git" "$SIGIL_HOME"
81
+ fi
82
+ else
83
+ warn "git not found — downloading a source tarball instead."
84
+ tmp="$(mktemp -d)"
85
+ curl -fsSL "https://github.com/$REPO/archive/refs/heads/$REF.tar.gz" -o "$tmp/src.tgz" \
86
+ || curl -fsSL "https://github.com/$REPO/archive/refs/tags/$REF.tar.gz" -o "$tmp/src.tgz" \
87
+ || die "could not download Sigil source for '$REF'."
88
+ tar -xzf "$tmp/src.tgz" -C "$tmp"
89
+ src="$(find "$tmp" -maxdepth 1 -type d -name 'sigil-*' | head -1)"
90
+ [ -n "$src" ] || die "unexpected tarball layout."
91
+ rm -rf "$SIGIL_HOME"; mv "$src" "$SIGIL_HOME"; rm -rf "$tmp"
92
+ fi
93
+ [ -f "$SIGIL_HOME/src/main.jac" ] || die "Sigil source looks incomplete (no src/main.jac in $SIGIL_HOME)."
94
+
95
+ # ---- 2. the jac this Sigil pins ----------------------------------------------
96
+ # PINNED: jac ships breaking changes as clean breaks, so Sigil runs on exactly the
97
+ # jac it was tested against. The pin is jac.toml's `jac-version` in the tree just
98
+ # fetched, so a release's installer and the tree it installs cannot disagree.
99
+ # Unpinned, this installed whatever jac was newest — v0.37 made a jac.toml table
100
+ # a hard error and every fresh install broke. Worse, an existing jac was kept
101
+ # whatever its version, so `sigil update` left every earlier install (jac 0.36.1)
102
+ # on a jac whose `jac run` rejects the flags this tree passes.
103
+ DEFAULT_JAC_VERSION="0.37.25" # for a tree from before jac.toml carried the pin
104
+ pinned="$(sed -n 's/^jac-version *= *"=*\([0-9][0-9.]*\)".*/\1/p' "$SIGIL_HOME/jac.toml" 2>/dev/null | head -1 || true)"
105
+ JAC_VERSION="${JAC_VERSION:-${pinned:-$DEFAULT_JAC_VERSION}}"
106
+ jac_ver() { "$1" --version 2>/dev/null | sed -n 's/^jac \([0-9][0-9.]*\).*/\1/p' | head -1 || true; }
107
+
108
+ JAC_BIN="$(command -v jac 2>/dev/null || true)"
109
+ found="${JAC_BIN:+$(jac_ver "$JAC_BIN")}"
110
+ if [ -n "$JAC_BIN" ] && [ "$found" = "$JAC_VERSION" ]; then
111
+ info "Found jac $JAC_VERSION: $JAC_BIN"
112
+ else
113
+ if [ -n "$JAC_BIN" ]; then
114
+ info "Found jac ${found:-of unknown version} at $JAC_BIN; this Sigil runs on jac $JAC_VERSION — installing it to ~/.local/bin…"
115
+ else
116
+ info "Installing the native jac runtime (v${JAC_VERSION})…"
117
+ fi
118
+ curl -fsSL https://raw.githubusercontent.com/jaseci-labs/jaseci/main/scripts/install.sh \
119
+ | bash -s -- --version "$JAC_VERSION" \
120
+ || die "jac $JAC_VERSION install failed. See https://www.jac-lang.org for manual instructions."
121
+ export PATH="$HOME/.local/bin:$PATH"
122
+ JAC_BIN="$HOME/.local/bin/jac"
123
+ got="$(jac_ver "$JAC_BIN")"
124
+ [ "$got" = "$JAC_VERSION" ] || die "installed jac reports '${got:-nothing}', expected $JAC_VERSION ($JAC_BIN)."
125
+ # An older jac EARLIER on your PATH (a venv, conda, /usr/local) still answers to
126
+ # `jac` in your shell. Sigil does not care — the launcher below is pinned to
127
+ # this binary — but you should know which one you get when you type `jac`.
128
+ shadow="$(PATH="$ORIG_PATH" command -v jac 2>/dev/null || true)"
129
+ if [ -n "$shadow" ] && [ "$shadow" != "$JAC_BIN" ]; then
130
+ warn "your PATH finds another jac first ($shadow, $(jac_ver "$shadow")). Sigil uses $JAC_BIN."
131
+ fi
132
+ fi
133
+
134
+ # ---- 3. runtime dependencies -------------------------------------------------
135
+ # Bare `jac install` provisions two things at once: jac.toml's [dependencies] (pyyaml
136
+ # for the AG-IR compiler, rich + prompt_toolkit for the `chat` REPL) AND the capability
137
+ # closures jac derives from the config — among them `llm`, which is what puts the
138
+ # litellm/pillow/loguru model backend on disk.
139
+ #
140
+ # That second half is why jac.toml carries a top-level [byllm] section. Through jac 0.34
141
+ # the runtime closure shipped litellm itself and the section did nothing; 0.36 dropped it
142
+ # from the closure, leaving it an optional dep of byLLM that jac resolves only for a
143
+ # project whose config asks for the `llm` capability. Miss the opt-in and the install
144
+ # still reports success — byLLM just falls back to its stub and every model call dies
145
+ # later with an unreadable AttributeError.
146
+ # Do NOT re-list packages here: an explicit list silently drifts from jac.toml, and
147
+ # a dependency added there but missed here breaks that feature on a fresh install
148
+ # (this is exactly how `sigil chat` shipped broken with "No module named 'rich'").
149
+ info "Provisioning dependencies (LLM runtime, chat REPL, everything jac.toml declares)…"
150
+ # Keep the output: this is the first place an incompatible jac shows itself, and
151
+ # discarding stderr turned "your runtime cannot parse jac.toml" into a one-line
152
+ # warning nobody could act on. Same reasoning as the byLLM probe below — an
153
+ # install that reports success while being unusable is the failure worth catching.
154
+ if ! dep_log="$( cd "$SIGIL_HOME" && "$JAC_BIN" install 2>&1 )"; then
155
+ warn "dependency install failed — Sigil will not run until this is fixed:"
156
+ printf '%s\n' "$dep_log" | sed 's/^/ /' >&2
157
+ case "$dep_log" in
158
+ *"jac.toml is invalid"*)
159
+ warn " this jac ($("$JAC_BIN" --version 2>/dev/null | head -1)) cannot parse Sigil's jac.toml"
160
+ warn " (JAC_VERSION=$JAC_VERSION; the tree pins ${pinned:-nothing})."
161
+ ;;
162
+ *) warn " re-run \`$JAC_BIN install\` in $SIGIL_HOME before your first solve." ;;
163
+ esac
164
+ fi
165
+
166
+ # An install that "succeeds" with no model backend is the one failure worth catching
167
+ # here, because nothing else notices until the user's first solve. Ask byLLM directly
168
+ # whether its litellm backend resolved rather than trusting the exit code above.
169
+ probe_dir="$(mktemp -d)"
170
+ cat > "$probe_dir/probe.jac" <<'PROBE'
171
+ with entry {
172
+ import from jaclang.byllm._optdeps.litellm { HAS_LITELLM }
173
+ print("sigil-llm-ok" if HAS_LITELLM else "sigil-llm-missing");
174
+ }
175
+ PROBE
176
+ probe_out="$( cd "$SIGIL_HOME" && "$JAC_BIN" run --no-serve "$probe_dir/probe.jac" 2>/dev/null || true )"
177
+ case "$probe_out" in
178
+ *sigil-llm-ok*)
179
+ info "LLM runtime ready (byLLM + litellm)."
180
+ ;;
181
+ *)
182
+ warn "byLLM resolved no litellm backend — model calls will fail on the first solve."
183
+ warn " fix: cd $SIGIL_HOME && $JAC_BIN install (jac.toml must keep its top-level [byllm] section)"
184
+ ;;
185
+ esac
186
+ rm -rf "$probe_dir"
187
+
188
+ # ---- 4. launcher on PATH -----------------------------------------------------
189
+ mkdir -p "$BIN_DIR"
190
+ cat > "$BIN_DIR/sigil" <<EOF
191
+ #!/usr/bin/env bash
192
+ # Sigil launcher shim — installed by install.sh
193
+ # Capture the invocation directory BEFORE cd-ing, or the wrapper's
194
+ # SIGIL_PWD default records the app dir and every relative path the
195
+ # user typed (e.g. \`sigil compile ./SKILL.md\`) resolves wrong.
196
+ export SIGIL_PWD="\${SIGIL_PWD:-\$PWD}"
197
+ # The jac this install verified (jac.toml's pin) — not whichever \`jac\` a
198
+ # later shell finds first. SIGIL_JAC set by the caller still wins.
199
+ export SIGIL_JAC="\${SIGIL_JAC:-$JAC_BIN}"
200
+ cd "$SIGIL_HOME" && exec ./sigil "\$@"
201
+ EOF
202
+ chmod +x "$BIN_DIR/sigil"
203
+ chmod +x "$SIGIL_HOME/sigil" 2>/dev/null || true
204
+
205
+ # ---- done --------------------------------------------------------------------
206
+ printf '\n%s ✓ Sigil installed%s\n\n' "$G" "$D"
207
+ printf ' source %s\n' "$SIGIL_HOME"
208
+ printf ' launcher %s\n\n' "$BIN_DIR/sigil"
209
+
210
+ case "${SIGIL_PATH_CHECK:-1}:$ORIG_PATH:" in
211
+ 0:*|false:*|no:*|off:*) : ;;
212
+ *":$BIN_DIR:"*) : ;;
213
+ *) warn "add the launcher to your PATH: export PATH=\"$BIN_DIR:\$PATH\"" ;;
214
+ esac
215
+
216
+ cat <<'EOF'
217
+
218
+ Next:
219
+ export OPENAI_API_KEY=sk-... # a model key (or point it at a local model)
220
+
221
+ # just use it — runs locally, no server needed:
222
+ sigil solve "turn report.pdf into a clean CSV"
223
+ sigil soul | sigil tasks list | sigil chat
224
+
225
+ # optional — a live web dashboard to watch it work:
226
+ sigil serve # Observatory web UI + HTTP API
227
+
228
+ Docs: https://sigilagent.com · https://github.com/sigilagent/sigil
229
+ EOF
package/package.json CHANGED
@@ -1,6 +1,36 @@
1
1
  {
2
2
  "name": "@sigilagent/sigil",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.6.1",
4
+ "description": "The skill compiler: SKILL.md compiled through a typed AG-IR into a runnable agent harness, so any model (small and local included) follows the skill by construction.",
5
+ "keywords": [
6
+ "agent",
7
+ "skills",
8
+ "compiler",
9
+ "llm",
10
+ "jac",
11
+ "mcp"
12
+ ],
13
+ "homepage": "https://sigilagent.com",
14
+ "bugs": "https://github.com/sigilagent/sigil/issues",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/sigilagent/sigil.git",
18
+ "directory": "npm"
19
+ },
20
+ "license": "MIT",
21
+ "author": "Jayanaka Dantanarayana",
22
+ "bin": {
23
+ "sigil": "bin/sigil"
24
+ },
25
+ "files": [
26
+ "bin/",
27
+ "install.sh"
28
+ ],
29
+ "os": [
30
+ "darwin",
31
+ "linux"
32
+ ],
33
+ "scripts": {
34
+ "prepublishOnly": "test -f install.sh && test \"$npm_package_version\" != 0.0.0"
35
+ }
36
+ }