@jigging/jig 0.1.0-alpha.22 → 0.1.0-alpha.24
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 +12 -1
- package/THIRD_PARTY_NOTICES +5 -1
- package/dist/index.js +6 -1
- package/dist/project/author.d.ts +2 -0
- package/libexec/agent/codex-acp.js +24 -9
- package/libexec/authoring/contract-authoring-worker.js +1 -2
- package/libexec/authoring/node_modules/@jigging/flow-authoring/README.md +6 -7
- package/libexec/authoring/node_modules/@jigging/flow-authoring/dist/index.d.ts +0 -1
- package/libexec/authoring/node_modules/@jigging/flow-authoring/dist/index.js +1 -9
- package/libexec/authoring/node_modules/@jigging/flow-authoring/dist/lower.d.ts +1 -1
- package/libexec/authoring/node_modules/@jigging/flow-authoring/dist/lower.js +1 -5
- package/libexec/authoring/node_modules/@jigging/flow-authoring/dist/worker.js +2 -2
- package/libexec/evaluator/project-authoring-1.schema.json +16 -2
- package/libexec/evaluator/project-evaluator-sdk.bundle.js +6 -1
- package/libexec/installed-cli.js +4277 -3716
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ jig new <name>
|
|
|
44
44
|
jig review [project] [--generate-contracts] [--allow-resolution-network] [--allow-authority-changes] [--yes] [--details]
|
|
45
45
|
jig run [flow:path|npm:package|binding:id] [options]
|
|
46
46
|
jig inspect [flow:path|npm:package|binding:id] [--json]
|
|
47
|
-
jig import-contract <
|
|
47
|
+
jig import-contract <descriptor.json|npm:package> <destination>
|
|
48
48
|
jig completion <bash|zsh|fish>
|
|
49
49
|
```
|
|
50
50
|
|
|
@@ -69,6 +69,17 @@ network socket. See [delegated HTTP access](https://jig.md/guide/http).
|
|
|
69
69
|
managed JSON and types before the separate execution-approval question. Plain
|
|
70
70
|
review does not compile; already-generated contracts need no compiler runtime.
|
|
71
71
|
|
|
72
|
+
Declare a project starting point using familiar Run arguments in `jig.ts`:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
entrypoint: "binding:factory --input @batch.json --attach source=fixtures --out factory-result --timeout 8m",
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
After review, `jig run` uses that entrypoint. Explicit options override defaults;
|
|
79
|
+
an explicit target bypasses them. Declaration paths are project-relative and job
|
|
80
|
+
files are captured when invoked. Existing output destinations are never replaced.
|
|
81
|
+
A target-only string is valid too. See [project entrypoints](https://jig.md/guide/configuration#project-entrypoint).
|
|
82
|
+
|
|
72
83
|
`inspect` lists approved targets or shows a target's retained interface without
|
|
73
84
|
evaluating source, contacting providers, preparing dependencies or changing state.
|
|
74
85
|
It checks that approval against current local execution identities and reports
|
package/THIRD_PARTY_NOTICES
CHANGED
|
@@ -84,7 +84,11 @@ Jig patches the pinned adapter to disable automatic model-based session titles.
|
|
|
84
84
|
Requested turns keep their reviewed model and count; deterministic fallback
|
|
85
85
|
titles remain. The patch also propagates native process failure and clears the
|
|
86
86
|
shutdown timer after native close. Forced termination cannot report a clean
|
|
87
|
-
adapter exit.
|
|
87
|
+
adapter exit. It also registers pending turns before asynchronous prompt setup
|
|
88
|
+
so immediate cancellation waits for and interrupts the correct native turn.
|
|
89
|
+
The adapter waits for the matching native turn-start notification before
|
|
90
|
+
exposing the turn as interruptible; a start reply alone does not establish it.
|
|
91
|
+
See `packages/jig/patches/codex-acp@1.8.0.patch` and its companion
|
|
88
92
|
note for the correction and removal condition.
|
|
89
93
|
|
|
90
94
|
Copyright 2025 JetBrains s.r.o.
|
package/dist/index.js
CHANGED
|
@@ -1997,7 +1997,7 @@ function defineJig(input) {
|
|
|
1997
1997
|
}
|
|
1998
1998
|
function normalizeJig(input, canonical) {
|
|
1999
1999
|
const captured = snapshotJsonObject(input, "Jig definition");
|
|
2000
|
-
assertClosedObject(captured, ["flows", "bindings", "grants", "defaultProviders"], "Jig definition");
|
|
2000
|
+
assertClosedObject(captured, ["flows", "bindings", "grants", "defaultProviders", "entrypoint"], "Jig definition");
|
|
2001
2001
|
const output = {};
|
|
2002
2002
|
if (Object.hasOwn(captured, "flows")) {
|
|
2003
2003
|
output.flows = normalizeSource(captured.flows, "flows", canonical);
|
|
@@ -2011,6 +2011,11 @@ function normalizeJig(input, canonical) {
|
|
|
2011
2011
|
if (Object.hasOwn(captured, "defaultProviders")) {
|
|
2012
2012
|
output.defaultProviders = normalizeDefaultProviders(captured.defaultProviders);
|
|
2013
2013
|
}
|
|
2014
|
+
if (Object.hasOwn(captured, "entrypoint")) {
|
|
2015
|
+
if (typeof captured.entrypoint !== "string" || captured.entrypoint.trim().length === 0 || captured.entrypoint.length > 16384)
|
|
2016
|
+
throw new TypeError("entrypoint must be a nonempty string of at most 16384 characters");
|
|
2017
|
+
output.entrypoint = captured.entrypoint;
|
|
2018
|
+
}
|
|
2014
2019
|
return record(output);
|
|
2015
2020
|
}
|
|
2016
2021
|
function normalizeDefaultProviders(value) {
|
package/dist/project/author.d.ts
CHANGED
|
@@ -15,12 +15,14 @@ export interface JigDefinition {
|
|
|
15
15
|
readonly bindings?: ProjectSource;
|
|
16
16
|
readonly grants?: ProjectSource;
|
|
17
17
|
readonly defaultProviders?: Readonly<Record<string, string>>;
|
|
18
|
+
readonly entrypoint?: string;
|
|
18
19
|
}
|
|
19
20
|
export interface JigDefinitionInput {
|
|
20
21
|
readonly flows?: ProjectSourceInput;
|
|
21
22
|
readonly bindings?: ProjectSourceInput;
|
|
22
23
|
readonly grants?: ProjectSourceInput;
|
|
23
24
|
readonly defaultProviders?: Readonly<Record<string, string>>;
|
|
25
|
+
readonly entrypoint?: string;
|
|
24
26
|
}
|
|
25
27
|
export interface FlowRef {
|
|
26
28
|
readonly kind: 'flow';
|
|
@@ -29076,7 +29076,7 @@ var CodexAppServerClient = class {
|
|
|
29076
29076
|
if (this.handleStaleTurnNotification(serverNotification, routing)) {
|
|
29077
29077
|
return;
|
|
29078
29078
|
}
|
|
29079
|
-
this.recordTurnRouting(routing);
|
|
29079
|
+
this.recordTurnRouting(routing, serverNotification.method);
|
|
29080
29080
|
if (this.handleStaleTurnNotification(serverNotification, routing)) {
|
|
29081
29081
|
return;
|
|
29082
29082
|
}
|
|
@@ -29155,19 +29155,33 @@ var CodexAppServerClient = class {
|
|
|
29155
29155
|
}
|
|
29156
29156
|
async runTurn(params, onTurnStarted) {
|
|
29157
29157
|
const capturedCompletions = [];
|
|
29158
|
+
const startedTurns = new Set();
|
|
29159
|
+
let expectedTurnId = null;
|
|
29160
|
+
let resolveReady = () => {};
|
|
29161
|
+
const ready = new Promise((resolve) => { resolveReady = resolve; });
|
|
29162
|
+
const releaseRouting = this.captureTurnRoutings(params.threadId, (turnId, method) => {
|
|
29163
|
+
if (method !== "turn/started") return;
|
|
29164
|
+
startedTurns.add(turnId);
|
|
29165
|
+
if (turnId === expectedTurnId) resolveReady();
|
|
29166
|
+
});
|
|
29158
29167
|
const releaseCapture = this.captureTurnCompletions(params.threadId, (event) => {
|
|
29159
29168
|
capturedCompletions.push(event);
|
|
29169
|
+
if (event.turn.id === expectedTurnId) resolveReady();
|
|
29160
29170
|
});
|
|
29161
29171
|
try {
|
|
29162
29172
|
const turnStarted = await this.turnStart(params);
|
|
29163
|
-
|
|
29164
|
-
|
|
29173
|
+
expectedTurnId = turnStarted.turn.id;
|
|
29174
|
+
// A turn/start reply allocates an ID before the native turn is interruptible.
|
|
29175
|
+
if (!startedTurns.has(expectedTurnId) && !capturedCompletions.some((event) => event.turn.id === expectedTurnId)) {
|
|
29176
|
+
await ready;
|
|
29177
|
+
}
|
|
29178
|
+
const earlyCompletion = capturedCompletions.find((event) => event.turn.id === expectedTurnId);
|
|
29179
|
+
if (earlyCompletion) return earlyCompletion;
|
|
29180
|
+
onTurnStarted?.(expectedTurnId);
|
|
29165
29181
|
releaseCapture();
|
|
29166
|
-
|
|
29167
|
-
return earlyCompletion;
|
|
29168
|
-
}
|
|
29169
|
-
return await this.awaitTurnCompleted(params.threadId, turnStarted.turn.id);
|
|
29182
|
+
return await this.awaitTurnCompleted(params.threadId, expectedTurnId);
|
|
29170
29183
|
} finally {
|
|
29184
|
+
releaseRouting();
|
|
29171
29185
|
releaseCapture();
|
|
29172
29186
|
}
|
|
29173
29187
|
}
|
|
@@ -29601,7 +29615,7 @@ var CodexAppServerClient = class {
|
|
|
29601
29615
|
capture();
|
|
29602
29616
|
}
|
|
29603
29617
|
}
|
|
29604
|
-
recordTurnRouting(routing) {
|
|
29618
|
+
recordTurnRouting(routing, method) {
|
|
29605
29619
|
if (routing.threadId === null || routing.turnId === null) {
|
|
29606
29620
|
return;
|
|
29607
29621
|
}
|
|
@@ -29610,7 +29624,7 @@ var CodexAppServerClient = class {
|
|
|
29610
29624
|
return;
|
|
29611
29625
|
}
|
|
29612
29626
|
for (const capture of captures) {
|
|
29613
|
-
capture(routing.turnId);
|
|
29627
|
+
capture(routing.turnId, method);
|
|
29614
29628
|
}
|
|
29615
29629
|
}
|
|
29616
29630
|
handleStaleTurnNotification(notification, routing) {
|
|
@@ -33453,6 +33467,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33453
33467
|
}
|
|
33454
33468
|
return pendingTurnStart;
|
|
33455
33469
|
};
|
|
33470
|
+
ensurePendingTurnStart();
|
|
33456
33471
|
const disposePromptRequestCancellation = this.observePromptRequestCancellation(signal, sessionState, activePrompt);
|
|
33457
33472
|
let eventHandler = null;
|
|
33458
33473
|
let promptNotificationsActive = true;
|
|
@@ -20,7 +20,7 @@ async function execute() {
|
|
|
20
20
|
try {
|
|
21
21
|
if (Number(process.versions.node.split('.')[0]) < 22)
|
|
22
22
|
throw new Error('Node 22 required');
|
|
23
|
-
const { source
|
|
23
|
+
const { source } = JSON.parse(input);
|
|
24
24
|
let types = true;
|
|
25
25
|
if (source.startsWith('// flow-authoring: ')) {
|
|
26
26
|
const header = JSON.parse(source.split('\n', 1)[0].slice(19));
|
|
@@ -30,7 +30,6 @@ async function execute() {
|
|
|
30
30
|
}
|
|
31
31
|
const result = await compileContract(await stampSource(source, { types }), {
|
|
32
32
|
signal: stop.signal,
|
|
33
|
-
...(channelContracts === undefined ? {} : { channelContracts }),
|
|
34
33
|
});
|
|
35
34
|
process.stdout.write(JSON.stringify({ source: result.source, artifacts: result.artifacts }) + '\n', () => process.exit(0));
|
|
36
35
|
}
|
|
@@ -33,13 +33,12 @@ options, not a function to call silently when opening an unfamiliar package.
|
|
|
33
33
|
It returns new source text; the application chooses whether to retain it.
|
|
34
34
|
`compileContract` requires that pin and refuses a different installed toolchain.
|
|
35
35
|
|
|
36
|
-
For borrowed agreements,
|
|
37
|
-
|
|
38
|
-
The
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
and 128 KiB; the native contract's smaller closure limits still apply.
|
|
36
|
+
For borrowed agreements, name a package-relative path in the authored channel
|
|
37
|
+
port. The compiler emits that reference without reading or inventorying package
|
|
38
|
+
files. The caller must validate and distribute the referenced JSON bytes with
|
|
39
|
+
the descriptor; Jig's managed workflow resolves only exact references and
|
|
40
|
+
tracks borrowed-input freshness separately from generated-file ownership.
|
|
41
|
+
Native contract closure limits still apply.
|
|
43
42
|
|
|
44
43
|
A minimal authored body is:
|
|
45
44
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Worker } from 'node:worker_threads';
|
|
2
2
|
import { AuthoringError, fail } from './errors.js';
|
|
3
3
|
import { getToolchain, readHeader } from './toolchain.js';
|
|
4
|
-
import { channelReference } from './values.js';
|
|
5
4
|
export { AuthoringError } from './errors.js';
|
|
6
5
|
export { getToolchain, stampSource } from './toolchain.js';
|
|
7
6
|
/** Compile explicit source into a bounded artifact packet, with no publication. */
|
|
@@ -15,18 +14,11 @@ export async function compileContract(source, options = {}) {
|
|
|
15
14
|
if (options.signal?.aborted)
|
|
16
15
|
fail('CANCELLED', 'Compilation was cancelled before it started.');
|
|
17
16
|
const header = readHeader(source, await getToolchain());
|
|
18
|
-
const channelContracts = options.channelContracts ?? [];
|
|
19
|
-
if (!Array.isArray(channelContracts) ||
|
|
20
|
-
channelContracts.length > 4096 ||
|
|
21
|
-
channelContracts.some((path) => !channelReference(path)) ||
|
|
22
|
-
Buffer.byteLength(JSON.stringify(channelContracts)) > 131072 ||
|
|
23
|
-
new Set(channelContracts).size !== channelContracts.length)
|
|
24
|
-
fail('SOURCE_INVALID', 'Supply at most 4096 distinct package-local channel contract paths within 128 KiB.');
|
|
25
17
|
if (options.signal?.aborted)
|
|
26
18
|
fail('CANCELLED', 'Compilation was cancelled before it started.');
|
|
27
19
|
return new Promise((resolve, reject) => {
|
|
28
20
|
const worker = new Worker(new URL('./worker.js', import.meta.url), {
|
|
29
|
-
workerData: { source, types: header.types
|
|
21
|
+
workerData: { source, types: header.types },
|
|
30
22
|
env: {},
|
|
31
23
|
execArgv: [],
|
|
32
24
|
stdout: true,
|
|
@@ -48,7 +48,7 @@ interface ChannelDescriptor {
|
|
|
48
48
|
}
|
|
49
49
|
export declare const schemaId = "https://flow.jig.md/schemas/schema-0.json";
|
|
50
50
|
export declare const contractId = "https://flow.jig.md/schemas/invocation-contract-0.schema.json";
|
|
51
|
-
export declare function lower(program: Program
|
|
51
|
+
export declare function lower(program: Program): {
|
|
52
52
|
descriptor: Descriptor;
|
|
53
53
|
projections: Record<string, {
|
|
54
54
|
$schema: string;
|
|
@@ -25,7 +25,7 @@ function number(value, target) {
|
|
|
25
25
|
}
|
|
26
26
|
return n === 0 ? 0 : n;
|
|
27
27
|
}
|
|
28
|
-
export function lower(program
|
|
28
|
+
export function lower(program) {
|
|
29
29
|
const entries = [...program.stateMap(invocationKey)];
|
|
30
30
|
if (entries.length !== 1)
|
|
31
31
|
fail('SOURCE_INVALID', 'Declare exactly one @invocation on a namespace.');
|
|
@@ -258,10 +258,6 @@ export function lower(program, channelContracts = new Set()) {
|
|
|
258
258
|
$defs: reachableDefinitions(emit(type), definitions),
|
|
259
259
|
};
|
|
260
260
|
}
|
|
261
|
-
for (const port of Object.values(ports)) {
|
|
262
|
-
if (!Object.hasOwn(channels, port.contract.slice(2)) && !channelContracts.has(port.contract))
|
|
263
|
-
fail('SOURCE_INVALID', 'Every port must reference a generated channel or a supplied offline contract.', owner, port.contract);
|
|
264
|
-
}
|
|
265
261
|
const projections = Object.create(null);
|
|
266
262
|
for (const [type, path] of program.stateMap(projectionKey)) {
|
|
267
263
|
if (!authored(type) ||
|
|
@@ -4,8 +4,8 @@ import { compileProgram } from './host.js';
|
|
|
4
4
|
import { lower } from './lower.js';
|
|
5
5
|
import { checkText, encode } from './values.js';
|
|
6
6
|
try {
|
|
7
|
-
const { source, types
|
|
8
|
-
const result = lower(await compileProgram(source)
|
|
7
|
+
const { source, types } = workerData;
|
|
8
|
+
const result = lower(await compileProgram(source));
|
|
9
9
|
const artifacts = Object.create(null);
|
|
10
10
|
artifacts['FLOW.contract.json'] = encode(result.descriptor);
|
|
11
11
|
for (const [path, schema] of Object.entries(result.projections))
|
|
@@ -96,6 +96,12 @@
|
|
|
96
96
|
"$ref": "#/$defs/defaultSelector"
|
|
97
97
|
},
|
|
98
98
|
"maxProperties": 256
|
|
99
|
+
},
|
|
100
|
+
"entrypoint": {
|
|
101
|
+
"type": "string",
|
|
102
|
+
"minLength": 1,
|
|
103
|
+
"maxLength": 16384,
|
|
104
|
+
"description": "An exact Run target followed by optional Jig run invocation arguments. Jig validates quoting, permitted options, project-relative paths and target membership. No shell execution or expansion."
|
|
99
105
|
}
|
|
100
106
|
},
|
|
101
107
|
"additionalProperties": false
|
|
@@ -167,8 +173,16 @@
|
|
|
167
173
|
}
|
|
168
174
|
},
|
|
169
175
|
"required": ["kind", "client"],
|
|
170
|
-
"if": {
|
|
171
|
-
|
|
176
|
+
"if": {
|
|
177
|
+
"required": ["retainSessions"]
|
|
178
|
+
},
|
|
179
|
+
"then": {
|
|
180
|
+
"properties": {
|
|
181
|
+
"client": {
|
|
182
|
+
"const": "codex"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
},
|
|
172
186
|
"additionalProperties": false
|
|
173
187
|
},
|
|
174
188
|
{
|
|
@@ -1997,7 +1997,7 @@ function defineJig(input) {
|
|
|
1997
1997
|
}
|
|
1998
1998
|
function normalizeJig(input, canonical) {
|
|
1999
1999
|
const captured = snapshotJsonObject(input, "Jig definition");
|
|
2000
|
-
assertClosedObject(captured, ["flows", "bindings", "grants", "defaultProviders"], "Jig definition");
|
|
2000
|
+
assertClosedObject(captured, ["flows", "bindings", "grants", "defaultProviders", "entrypoint"], "Jig definition");
|
|
2001
2001
|
const output = {};
|
|
2002
2002
|
if (Object.hasOwn(captured, "flows")) {
|
|
2003
2003
|
output.flows = normalizeSource(captured.flows, "flows", canonical);
|
|
@@ -2011,6 +2011,11 @@ function normalizeJig(input, canonical) {
|
|
|
2011
2011
|
if (Object.hasOwn(captured, "defaultProviders")) {
|
|
2012
2012
|
output.defaultProviders = normalizeDefaultProviders(captured.defaultProviders);
|
|
2013
2013
|
}
|
|
2014
|
+
if (Object.hasOwn(captured, "entrypoint")) {
|
|
2015
|
+
if (typeof captured.entrypoint !== "string" || captured.entrypoint.trim().length === 0 || captured.entrypoint.length > 16384)
|
|
2016
|
+
throw new TypeError("entrypoint must be a nonempty string of at most 16384 characters");
|
|
2017
|
+
output.entrypoint = captured.entrypoint;
|
|
2018
|
+
}
|
|
2014
2019
|
return record(output);
|
|
2015
2020
|
}
|
|
2016
2021
|
function normalizeDefaultProviders(value) {
|