@jigging/jig 0.1.0-alpha.10 → 0.1.0-alpha.11

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
@@ -33,14 +33,24 @@ independently validated; Jig fails closed when a required capability is absent.
33
33
  The alpha requires:
34
34
 
35
35
  - Linux x86_64 with glibc 2.17 or newer and an SSE4.2-capable baseline CPU;
36
- - Bubblewrap 0.12 or newer at `/usr/bin/bwrap`;
37
- - GNU `readlink -f` at `/usr/bin/readlink` or `/bin/readlink`;
36
+ - Bubblewrap 0.12 or newer and GNU `readlink -f`, located as described below;
38
37
  - cgroup v2 with delegated `cpu`, `memory`, and `pids` controllers;
39
38
  - a systemd user manager with transient delegated scopes; and
40
39
  - unprivileged user, mount, PID, network, IPC, UTS, and cgroup namespaces.
41
40
 
42
41
  The glibc and SSE4.2 floors come from the selected Bun baseline runtime.
43
42
 
43
+ Host tools are resolved through `/usr/bin`, `/bin`, or the NixOS system profile
44
+ `/run/current-system/sw/bin`, never ambient `PATH`. An operator may select
45
+ Bubblewrap using an absolute `JIG_BWRAP_PATH`, including a shell-local Nix
46
+ dependency. It receives the same validation and never falls back on failure.
47
+ On NixOS, enable
48
+ `programs.nix-ld.enable` for the unmodified npm runtime. Jig uses the real glibc
49
+ loader at the system-managed `share/nix-ld/lib/ld.so` link, mounting only that
50
+ loader and its required libraries into Runs. It does not mount nix-ld or the
51
+ whole Nix store. NixOS path support is included in this source candidate;
52
+ independent NixOS host conformance is not yet established.
53
+
44
54
  Jig commands do not use `sudo`, download runtimes, or expose host control to
45
55
  Flow code. Runtime installation is handled once by npm with the Jig package.
46
56
 
@@ -136,7 +146,7 @@ import { defineBinding } from "@jigging/jig";
136
146
 
137
147
  export default defineBinding({
138
148
  package: "./flows/reviewer",
139
- slots: { research: "./flows/research" },
149
+ slots: { research: "flow:flows/research" },
140
150
  });
141
151
  ```
142
152
 
@@ -145,21 +155,24 @@ jig run binding:reviewer --input '{}'
145
155
  ```
146
156
 
147
157
  `slots` is optional and omission normalizes to `{}`. It maps at most 256
148
- LocalName keys to other selected, direct-eligible Flow package paths in the
149
- same admitted generation. Slots belong to the Binding; a direct `flow:` Run
150
- has none.
158
+ LocalName keys to explicit `flow:<path>` or `binding:<id>` targets in the same
159
+ admitted generation. Slots belong to the Binding; a direct `flow:` Run has none.
160
+ Selected child Bindings must have no child slots of their own.
151
161
 
152
162
  Each `flow/call` carries JSON/1 input into a fresh child context and returns a
153
- complete JSON/1 Run result. The child receives empty settings and attachments,
154
- no inherited slots, and a deadline no later than its parent. Run/1 controls
163
+ complete JSON/1 Run result. The child receives its selected target's admitted
164
+ settings and Agent capability, empty attachments, no inherited slots, and a
165
+ deadline no later than its parent. It selects its own package-local Skills per
166
+ Agent call; providers and credentials remain host choices. Run/1 controls
155
167
  operation identity, duplicate joins, conflicting reuse, cancellation, and
156
168
  uncertainty; Jig does not replay uncertain dispatch automatically. There is no
157
169
  separate child history, administration, scheduler, catalogue, or resolver. Jig
158
170
  also never guesses an unprefixed target.
159
171
 
160
- The alpha admits one active child operation per parent; excess distinct
161
- concurrent calls receive `RESOURCE_EXHAUSTED`, while sequential calls remain
162
- available.
172
+ Each Run context admits one active operation; a child Flow can own one Agent
173
+ operation while its parent awaits it. Excess distinct concurrent calls receive
174
+ `RESOURCE_EXHAUSTED`, while sequential calls remain available. Cancellation and
175
+ cleanup cover the specialist and its locally owned Agent worker.
163
176
 
164
177
  One experimental [Agent Run capability](https://jig.md/spec/agent-run) is
165
178
  available through ordinary Run/1 `effect/call`. The host may use the official
package/bin/jig CHANGED
@@ -16,6 +16,8 @@ if [ -x /usr/bin/readlink ]; then
16
16
  readlink=/usr/bin/readlink
17
17
  elif [ -x /bin/readlink ]; then
18
18
  readlink=/bin/readlink
19
+ elif [ -x /run/current-system/sw/bin/readlink ]; then
20
+ readlink=/run/current-system/sw/bin/readlink
19
21
  else
20
22
  fail
21
23
  fi
package/dist/index.js CHANGED
@@ -1783,6 +1783,12 @@ function normalizeJig(input, canonical) {
1783
1783
  function defineBinding(input) {
1784
1784
  return normalizeBinding(input, false);
1785
1785
  }
1786
+ function flowRef(path) {
1787
+ return record({ kind: "flow", path: normalizeProjectPath(path, "Flow reference") });
1788
+ }
1789
+ function bindingRef(id) {
1790
+ return record({ kind: "binding", id: validateLocalName(id, "Binding reference") });
1791
+ }
1786
1792
  function normalizeBinding(input, canonical) {
1787
1793
  const captured = snapshotJsonObject(input, "Binding definition");
1788
1794
  assertClosedObject(captured, canonical ? ["kind", "package", "settings", "slots"] : ["package", "settings", "slots"], "Binding definition");
@@ -1804,10 +1810,20 @@ function normalizeFlowSlots(value) {
1804
1810
  const output = Object.create(null);
1805
1811
  for (const name of Object.keys(input).sort(compareUtf8)) {
1806
1812
  validateLocalName(name, "slot name");
1807
- output[name] = normalizeProjectPath(input[name], `slot ${name}`);
1813
+ const target = parseRunTargetSelector(input[name], `slot ${name}`);
1814
+ output[name] = target.kind === "flow" ? `flow:${target.path}` : `binding:${target.id}`;
1808
1815
  }
1809
1816
  return Object.freeze(output);
1810
1817
  }
1818
+ function parseRunTargetSelector(value, label) {
1819
+ if (typeof value !== "string")
1820
+ throw new TypeError(`${label} must be a target selector`);
1821
+ if (value.startsWith("flow:"))
1822
+ return flowRef(normalizeProjectPath(value.slice(5), label));
1823
+ if (value.startsWith("binding:"))
1824
+ return bindingRef(validateLocalName(value.slice(8), label));
1825
+ throw new TypeError(`${label} must select flow:<path> or binding:<id>`);
1826
+ }
1811
1827
  function normalizeSource(value, field, canonical) {
1812
1828
  if (value === undefined)
1813
1829
  throw new TypeError(`${field} cannot be undefined`);
@@ -47,3 +47,5 @@ export declare function flowRef(path: string): FlowRef;
47
47
  export declare function bindingRef(id: string): BindingRef;
48
48
  /** Evaluator-only canonical re-normalization; absent from the package root. */
49
49
  export declare function normalizePackageBindingDefinition(input: unknown): PackageBindingDefinition;
50
+ /** Internal selector parsing shared by authoring and exact project linking. */
51
+ export declare function parseRunTargetSelector(value: unknown, label: string): RunTargetRef;
@@ -20,6 +20,12 @@
20
20
  "minLength": 1,
21
21
  "maxLength": 1024
22
22
  },
23
+ "targetSelector": {
24
+ "type": "string",
25
+ "description": "An exact flow:<project-relative-path> or binding:<LocalName> selector. Jig additionally validates the prefix and canonical target identity.",
26
+ "minLength": 6,
27
+ "maxLength": 1029
28
+ },
23
29
  "discoverSource": {
24
30
  "type": "object",
25
31
  "properties": {
@@ -99,7 +105,7 @@
99
105
  "slots": {
100
106
  "type": "object",
101
107
  "additionalProperties": {
102
- "$ref": "#/$defs/projectPath"
108
+ "$ref": "#/$defs/targetSelector"
103
109
  },
104
110
  "maxProperties": 256
105
111
  }
@@ -1783,6 +1783,12 @@ function normalizeJig(input, canonical) {
1783
1783
  function defineBinding(input) {
1784
1784
  return normalizeBinding(input, false);
1785
1785
  }
1786
+ function flowRef(path) {
1787
+ return record({ kind: "flow", path: normalizeProjectPath(path, "Flow reference") });
1788
+ }
1789
+ function bindingRef(id) {
1790
+ return record({ kind: "binding", id: validateLocalName(id, "Binding reference") });
1791
+ }
1786
1792
  function normalizeBinding(input, canonical) {
1787
1793
  const captured = snapshotJsonObject(input, "Binding definition");
1788
1794
  assertClosedObject(captured, canonical ? ["kind", "package", "settings", "slots"] : ["package", "settings", "slots"], "Binding definition");
@@ -1804,10 +1810,20 @@ function normalizeFlowSlots(value) {
1804
1810
  const output = Object.create(null);
1805
1811
  for (const name of Object.keys(input).sort(compareUtf8)) {
1806
1812
  validateLocalName(name, "slot name");
1807
- output[name] = normalizeProjectPath(input[name], `slot ${name}`);
1813
+ const target = parseRunTargetSelector(input[name], `slot ${name}`);
1814
+ output[name] = target.kind === "flow" ? `flow:${target.path}` : `binding:${target.id}`;
1808
1815
  }
1809
1816
  return Object.freeze(output);
1810
1817
  }
1818
+ function parseRunTargetSelector(value, label) {
1819
+ if (typeof value !== "string")
1820
+ throw new TypeError(`${label} must be a target selector`);
1821
+ if (value.startsWith("flow:"))
1822
+ return flowRef(normalizeProjectPath(value.slice(5), label));
1823
+ if (value.startsWith("binding:"))
1824
+ return bindingRef(validateLocalName(value.slice(8), label));
1825
+ throw new TypeError(`${label} must select flow:<path> or binding:<id>`);
1826
+ }
1811
1827
  function normalizeSource(value, field, canonical) {
1812
1828
  if (value === undefined)
1813
1829
  throw new TypeError(`${field} cannot be undefined`);