@plurnk/plurnk-contracts 3.3.0 → 4.1.0
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/.env.defaults +17 -0
- package/README.md +3 -1
- package/SPEC.md +100 -85
- package/dist/conformance/agui-v1.json +308 -183
- package/dist/schema/A2aAgentDefinition.json +42 -10
- package/dist/schema/AguiDiscovery.json +1 -1
- package/dist/schema/PlurnkStatement.json +1 -1
- package/dist/schema/ProposalProjection.json +90 -14
- package/dist/src/Application.d.ts +253 -0
- package/dist/src/Application.d.ts.map +1 -0
- package/dist/src/Application.js +2 -0
- package/dist/src/Application.js.map +1 -0
- package/dist/src/ApplicationPort.d.ts +67 -147
- package/dist/src/ApplicationPort.d.ts.map +1 -1
- package/dist/src/Functionality.d.ts +2 -1
- package/dist/src/Functionality.d.ts.map +1 -1
- package/dist/src/HttpOrigin.d.ts +16 -0
- package/dist/src/HttpOrigin.d.ts.map +1 -0
- package/dist/src/HttpOrigin.js +15 -0
- package/dist/src/HttpOrigin.js.map +1 -0
- package/dist/src/Validator.d.ts +0 -1
- package/dist/src/Validator.d.ts.map +1 -1
- package/dist/src/Validator.js +0 -14
- package/dist/src/Validator.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/types.d.ts +11 -7
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.generated.d.ts +47 -22
- package/dist/src/types.generated.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/package.json +7 -3
- package/plurnk.md +46 -50
- package/dist/schema/ClientStatement.json +0 -104
package/.env.defaults
CHANGED
|
@@ -9,3 +9,20 @@ PLURNK_PORT=1066
|
|
|
9
9
|
# The whole URL a client dials instead: a remote portal, or a daemon bound to an address no
|
|
10
10
|
# client can dial (0.0.0.0). Unset = http://$PLURNK_HOST:$PLURNK_PORT/agui.
|
|
11
11
|
# PLURNK_AGUI_URL=
|
|
12
|
+
|
|
13
|
+
# Whether the daemon authenticates ({§credential-authority}): 1 = every request to the client
|
|
14
|
+
# interface and to the hosted agent presents a credential this daemon issued, and the daemon serves
|
|
15
|
+
# the authorization server that issues them; 0 = no credential exists and every request is
|
|
16
|
+
# anonymous, for a harness driving a daemon of its own. The posture is this value, never inferred
|
|
17
|
+
# from what else is set.
|
|
18
|
+
PLURNK_AUTH=1
|
|
19
|
+
# The operator's client secret ({§agui-oauth-clients}): what the terminal client and every other
|
|
20
|
+
# tool of yours exchanges for access tokens. Unset, the daemon mints one at every boot into the
|
|
21
|
+
# file `secret` beside its database (0600), where a tool running as you reads it. Set it here, and
|
|
22
|
+
# the same value in the tool's environment, for a tool on another host or under another user.
|
|
23
|
+
# PLURNK_SECRET=
|
|
24
|
+
# The operator's browser sign-in ({§agui-oauth-login}): the password a browser signs in with,
|
|
25
|
+
# compared in constant time at the authorization endpoint. No browser is the operator without it:
|
|
26
|
+
# while it is empty, the sign-in page says so and where to set it, and admits nobody
|
|
27
|
+
# ({§agui-oauth-session}). The terminal client and your other tools use PLURNK_SECRET instead.
|
|
28
|
+
PLURNK_PASS=
|
package/README.md
CHANGED
|
@@ -52,7 +52,9 @@ Validator.assertOperationResult(result);
|
|
|
52
52
|
|
|
53
53
|
Generated wire types, constructors, and validators share the package root entry
|
|
54
54
|
point described by SPEC {§wire-entrypoint}. Owning JSON Schemas use the published
|
|
55
|
-
`@plurnk/plurnk-contracts/schema/*.json` subpaths.
|
|
55
|
+
`@plurnk/plurnk-contracts/schema/*.json` subpaths. The root is runtime-neutral, so
|
|
56
|
+
a browser type-checks it without Node; the application port that modules consume,
|
|
57
|
+
which names Node's HTTP types, is `@plurnk/plurnk-contracts/port` ({§runtime-neutral-root}).
|
|
56
58
|
|
|
57
59
|
## Development
|
|
58
60
|
|
package/SPEC.md
CHANGED
|
@@ -16,7 +16,7 @@ runtime-neutral wire envelopes; `@plurnk/plurnk-parser` implements the language
|
|
|
16
16
|
| Stopped-world client contract | `ProposalDisposition`, `ProposalProjection` |
|
|
17
17
|
| Client-owned interaction contract | `ClientInteractionRequest`, `ClientInteractionProjection`, `ClientInteractionResolution` |
|
|
18
18
|
| Client capability presentation | `ClientDisplayCapabilities` |
|
|
19
|
-
| Exterior adapter application calls | `ApplicationPort`
|
|
19
|
+
| Exterior adapter application calls | `ApplicationPort`, from `@plurnk/plurnk-contracts/port` ({§runtime-neutral-root}) |
|
|
20
20
|
| Workspace MCP configuration | `McpServerDefinition`, `McpOAuth` |
|
|
21
21
|
| Worker Agent Skills definition | `SkillDefinition` |
|
|
22
22
|
| Worker outbound A2A agent definition | `A2aAgentDefinition` |
|
|
@@ -295,11 +295,11 @@ wider bare fence nests where closing there would cost the reading more
|
|
|
295
295
|
({§fence-pairing}). A nested block ends at its first valid closer, as a CommonMark code block
|
|
296
296
|
does. So a wider outer fence holds any narrower body, finished or not, and equal widths nest
|
|
297
297
|
when every inner block closes. Preserve every nested body byte, including apparent operations
|
|
298
|
-
and
|
|
298
|
+
and executor invocations, without dispatching them. These rules apply equally to model programs,
|
|
299
299
|
stored programs, client operations, and reasoning quotations.
|
|
300
300
|
|
|
301
301
|
§operation-fences **Accept three or more backticks; teach and render three.** A line-start fence
|
|
302
|
-
of three or more backticks
|
|
302
|
+
of three or more backticks carrying an operation heading ({§executor-heading}) opens that
|
|
303
303
|
operation ({§indented-fences}), and no width draws a receipt. Three is the taught form and the
|
|
304
304
|
rendered form; a wider fence is the same statement, and it is how a body holding fence lines of
|
|
305
305
|
its own is held: an opener wider than any of them ({§balanced-fences}). Enclosing quotations
|
|
@@ -328,7 +328,7 @@ aside, an operand, or other heading text does not qualify and remains the unfenc
|
|
|
328
328
|
read this way.
|
|
329
329
|
|
|
330
330
|
§fence-heading-in-body Outside a complete nested block ({§balanced-fences}), a fence
|
|
331
|
-
line of three or more backticks
|
|
331
|
+
line of three or more backticks carrying a heading under {§executor-heading}
|
|
332
332
|
is a heading. Inside an open block it either ends that block without closing it and opens the
|
|
333
333
|
next statement, or it is a literal example held by the block. {§fence-pairing} chooses between
|
|
334
334
|
the two. Fence lines of
|
|
@@ -356,8 +356,8 @@ input at once by {§fence-pairing}:
|
|
|
356
356
|
| Indented four spaces or more, or by a tab | Body ({§indented-fences}) |
|
|
357
357
|
| Fewer backticks than the block's own, or another character | Body, or the opener of a nested block |
|
|
358
358
|
| At least the block's backticks, bare | The block's closer, or the opener of a nested block |
|
|
359
|
-
| Labeled,
|
|
360
|
-
| Three or more backticks
|
|
359
|
+
| Labeled, without an operation heading | The opener of a nested block, or body |
|
|
360
|
+
| Three or more backticks with an operation heading ({§executor-heading}) | A heading that ends the block, or a literal example |
|
|
361
361
|
|
|
362
362
|
### §fence-pairing Fence pairing
|
|
363
363
|
|
|
@@ -410,7 +410,7 @@ repaired reading: a complete nested interpretation takes precedence. Each class
|
|
|
410
410
|
| Counted | Complete readings | Repaired readings | Why |
|
|
411
411
|
|---|---|---|---|
|
|
412
412
|
| Hidden operations: a heading that will not run, written at its block's width or wider | 1, together with the next row | 1 | Every operation the author wrote should run |
|
|
413
|
-
| Repairs: a supplied closer (except a message's run to the end of the input, {§message-run-on}), a fence read as a stray, a narrower closer accepted, a body under an operation that takes none (
|
|
413
|
+
| Repairs: a supplied closer (except a message's run to the end of the input, {§message-run-on}), a fence read as a stray, a narrower closer accepted, a body under an operation that takes none (COPY, MOVE, non-log targeted KILL), a body not well-formed in the media type its runtime declares ({§executor-invocation}) | none by definition | 2 | The least-errors distance |
|
|
414
414
|
| Literal by declaration: a heading narrower than its block, or no wider than the labeled block or example holding it, or inside a quotation or a KILL, or an executor heading inside a SEND, WORK, FORK or BARE body ({§prose-code-blocks}); a labeled fence in a body read as text | 1, together with the row above | 3 | Every code block the author declared should stand |
|
|
415
415
|
| Supplied closers | 2 | 4 | A block the author opened should end at a fence the author wrote |
|
|
416
416
|
| Other fences read as text | 3 | 5 | The least departure from the fences as written |
|
|
@@ -499,12 +499,11 @@ by the next opener is {§inline-chain}, and by nothing is the ordinary {§fence-
|
|
|
499
499
|
no ambiguity to resolve: a slot begins with `<` or `[` and an opener with a backtick run, so the
|
|
500
500
|
shapes are disjoint.
|
|
501
501
|
|
|
502
|
-
§executor-case **An executor tag in any case.**
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
({§executor-js-spelling}) is still prose ({§interstitial-fence}).
|
|
502
|
+
§executor-case **An executor tag in any case.** An executor heading matches a
|
|
503
|
+
known executor's name case-insensitively (`SH` opens `sh`); its AST carries the
|
|
504
|
+
registered spelling when known, otherwise the lowercase name. Native operation
|
|
505
|
+
names remain case-sensitive. Recognition follows {§executor-heading}; availability
|
|
506
|
+
and permission are checked at dispatch, not granted by a recognized spelling.
|
|
508
507
|
|
|
509
508
|
§executor-js-spelling When `node` is registered and `js` is not, `js` names
|
|
510
509
|
`node` under {§executor-case}. Parsing normalizes the runtime before admission
|
|
@@ -529,8 +528,8 @@ line takes the rest of the line as the aside, with one warning-severity advisory
|
|
|
529
528
|
A closed aside followed by more text is unchanged.
|
|
530
529
|
|
|
531
530
|
§quotation **A fence that opens no operation quotes.** Outside a body, a line-start fence that
|
|
532
|
-
is not an operation heading — unlabeled
|
|
533
|
-
|
|
531
|
+
is not an operation heading ({§executor-heading}) — unlabeled or tagged like an unknown
|
|
532
|
+
code language (`ts`, `json`) without invocation slots — opens a
|
|
534
533
|
quotation that runs to its matching closer (same character, width at least the opener's) or to
|
|
535
534
|
the end of the input. Everything inside is data: no operation runs there and native tool-call
|
|
536
535
|
markup is not read ({§native-tool-calls}). An operation fenced inside an unlabeled code block
|
|
@@ -552,23 +551,29 @@ belongs in a properly nested body ({§balanced-fences}) or a quotation ({§quota
|
|
|
552
551
|
So a model may show plurnk's own operations in an answer. Two exceptions keep programs whole:
|
|
553
552
|
CommonMark's own rule that a backtick opener's line carries no further backtick, so
|
|
554
553
|
```` ```READ (x)``` ```` is inline code and quotes nothing after it; and a bare fence directly under
|
|
555
|
-
a line carrying a fence run, which is an orphaned closer and quotes nothing. An unknown tag
|
|
556
|
-
|
|
557
|
-
is an operation the model missed by its tag, and it draws one warning — `` `OP` is not an
|
|
558
|
-
operation or a known executor here. `` An offset example draws nothing either
|
|
554
|
+
a line carrying a fence run, which is an orphaned closer and quotes nothing. An unknown tag
|
|
555
|
+
without invocation slots is a code block and draws nothing. An offset example draws nothing either
|
|
559
556
|
({§indented-fences}). Quotation outside an operation is
|
|
560
557
|
response text under {§response-text}, not an executable program or a completion envelope.
|
|
561
558
|
|
|
562
559
|
`plurnk.md` names the tab offset as the form for an example, in the aside of its nesting
|
|
563
560
|
example, and shows its own examples offset; the other quoting fences are untaught: a tilde
|
|
564
|
-
fence, an unlabeled fence and an unknown tag all quote. Each is a shape a model reaches for from ordinary Markdown rather than from this
|
|
561
|
+
fence, an unlabeled fence and an unknown tag without invocation slots all quote. Each is a shape a model reaches for from ordinary Markdown rather than from this
|
|
565
562
|
teaching, so honouring it protects an example the model already believed was safe
|
|
566
563
|
({§outside-text} places the scale). The offset is the one form that survives every
|
|
567
564
|
fence style.
|
|
568
565
|
|
|
569
|
-
§
|
|
570
|
-
|
|
571
|
-
|
|
566
|
+
§executor-heading **Syntax identifies an invocation; dispatch resolves its runtime.** A native
|
|
567
|
+
operation or a known executor name opens a heading. An otherwise unknown fence name also opens an
|
|
568
|
+
executor heading when the next non-horizontal-whitespace character starts an invocation slot:
|
|
569
|
+
`(` for the target, `[` for metadata, or `<` for scope (not `<!--`, an aside). The same slot grammar
|
|
570
|
+
then validates and binds it, including malformed-slot diagnostics and permitted slot ordering.
|
|
571
|
+
Availability does not affect that parse. Known executors are the host's supplied vocabulary plus
|
|
572
|
+
`sh`; knowing a name also permits its targetless, slotless form. Enclosing quotations, indented
|
|
573
|
+
examples and reasoning-channel restrictions remain unchanged.
|
|
574
|
+
|
|
575
|
+
§interstitial-fence Only a heading under {§executor-heading} opens an operation. Any other fence
|
|
576
|
+
opens no operation: outside a block it quotes under {§quotation}, inside a body it is body.
|
|
572
577
|
|
|
573
578
|
§closer-aside A closing fence followed on its line by one aside and nothing else
|
|
574
579
|
is the closer; the aside is outside text. Read as body, that line would be written
|
|
@@ -655,7 +660,7 @@ beside owner metadata, not only a matcher carried inside its `pattern` option.
|
|
|
655
660
|
|
|
656
661
|
| Element | Contract |
|
|
657
662
|
|---|---|
|
|
658
|
-
| Fence name | Reserved native OP, otherwise
|
|
663
|
+
| Fence name | Reserved native OP, otherwise an executor name under {§executor-heading} |
|
|
659
664
|
| `(path)` | Target/program/tool slot; COPY and MOVE each have two resource operands |
|
|
660
665
|
| `[metadata]` | One owner-interpreted block; options, never the op's input |
|
|
661
666
|
| `<scope>` | Operation-specific numeric or anchored coordinates |
|
|
@@ -722,20 +727,18 @@ compact empty block or permit unmatched fences.
|
|
|
722
727
|
| KILL on a log target | The matcher. Beside an option block's `pattern`, the first line of the distillation ({§log-kill-distillation}). |
|
|
723
728
|
| EDIT | A sigil-led matcher ({§edit-pattern}), unless an option block carries the `pattern`; otherwise the body. |
|
|
724
729
|
| COPY, MOVE | Ignored ({§transfer-resource-selections}). |
|
|
725
|
-
| SEND, WORK, FORK, BARE
|
|
730
|
+
| SEND, WORK, FORK, BARE | One JSON object is the option block where the heading admits one ({§bare-option-object}); otherwise the body. |
|
|
731
|
+
| executors | The input body, including an unbracketed JSON object; metadata requires brackets. |
|
|
726
732
|
| NOTE, WAIT, KILL without a target | The body. |
|
|
727
733
|
|
|
728
734
|
§bare-option-object A bare option object is the option block, where the house option array owns the
|
|
729
|
-
block. On
|
|
730
|
-
every executor fence — heading text after the slots that is exactly one JSON object `{…}`, where the
|
|
735
|
+
block. On SEND, BARE, WORK and FORK, heading text after the slots that is exactly one JSON object `{…}`, where the
|
|
731
736
|
heading admits a block (BARE, WORK and FORK only after their target), is read
|
|
732
737
|
as `[{…}]`: the AST carries the array form, the written heading renders it, and one
|
|
733
738
|
warning-severity receipt names the indulgence in place of the {§heading-inline-body} advisory:
|
|
734
|
-
"`SEND` took a bare option object; the taught form is `[{…}]`."
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
written on the heading line — under {§heading-inline-body}. The host names those executors to the parse
|
|
738
|
-
(`ParseOptions.jsonBodyExecutors`). A heading that already carries a block keeps the object as
|
|
739
|
+
"`SEND` took a bare option object; the taught form is `[{…}]`." Executor headings always read an
|
|
740
|
+
unbracketed object as input under {§heading-inline-body}, regardless of registration or input media
|
|
741
|
+
type; their metadata is only the bracketed slot ({§scheme-metadata-modifier}). A heading that already carries a block keeps the object as
|
|
739
742
|
inline body. On FIND, READ and KILL the same text is the matcher
|
|
740
743
|
({§naked-pattern}), because a search for JSON text is legitimate; a bare matcher
|
|
741
744
|
that parses as a JSON object draws one advisory saying so: "`{…}` was read as the
|
|
@@ -744,8 +747,7 @@ matcher." ({§diagnostic-observation}).
|
|
|
744
747
|
§operation-aside The final header modifier may be one single-line HTML
|
|
745
748
|
comment. AstBuilder removes its delimiters and surrounding whitespace into
|
|
746
749
|
`aside: string | null`. It is durable descriptive text, not authority,
|
|
747
|
-
routing, timing, or body input. Comments inside a body remain literal
|
|
748
|
-
for the narrowly owned {§misplaced-aside-advisory}.
|
|
750
|
+
routing, timing, or body input. Comments inside a body remain literal.
|
|
749
751
|
|
|
750
752
|
§scheme-metadata-modifier A target may carry one single-line `[metadata]`
|
|
751
753
|
block, placed under {§slot-order}; executor and SEND fences also admit it without a target.
|
|
@@ -783,13 +785,10 @@ the owner verbatim, and the owner's reader treats `pattern` as reserved. The
|
|
|
783
785
|
language lifts only from one block that parses as a JSON array of objects;
|
|
784
786
|
anything else lifts nothing and reaches the owner's `400` untouched. A
|
|
785
787
|
`pattern` that is present but not a string is the language's own positioned
|
|
786
|
-
diagnostic, as is a matcher of a claimed dialect that fails admission. FIND
|
|
787
|
-
READ
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
matcher, and it never strikes ({§matcher-body-redirect}). The heading line itself
|
|
791
|
-
is the matcher's home ({§naked-pattern}). A body that is only an HTML comment is
|
|
792
|
-
still the aside under {§misplaced-aside-advisory}. EDIT keeps its literal body:
|
|
788
|
+
diagnostic, as is a matcher of a claimed dialect that fails admission. FIND and
|
|
789
|
+
READ bodies become memory under {§retrieval-annotation}; a non-log KILL's body is
|
|
790
|
+
unused and receives the advisory under {§matcher-body-redirect}. The heading line
|
|
791
|
+
is the matcher's home ({§naked-pattern}). EDIT keeps its literal body:
|
|
793
792
|
with a matcher it is the replacement for every selected span ({§edit-pattern}),
|
|
794
793
|
and an absent body deletes them. `PlurnkParser.stringify` writes a lifted matcher
|
|
795
794
|
whose block left no metadata back bare when the bare form reads back identically
|
|
@@ -814,8 +813,8 @@ governed by {§canonical-statement}; runtime conditions remain explicit below.
|
|
|
814
813
|
|
|
815
814
|
| OP | `(path)` | `<scope>` | `body` |
|
|
816
815
|
|------|----------------------------------------------|---------------------------------|--------------------------------|
|
|
817
|
-
| FIND | required target or glob | optional result range |
|
|
818
|
-
| READ | required target | optional text region |
|
|
816
|
+
| FIND | required target or glob | optional result range | annotation normalized to NOTE |
|
|
817
|
+
| READ | required target | optional text region | annotation normalized to NOTE |
|
|
819
818
|
| EDIT | required file or entry | required for an existing target | literal text |
|
|
820
819
|
| COPY | required source and destination | optional region after each path | empty |
|
|
821
820
|
| MOVE | required source and destination | optional region after each path | empty |
|
|
@@ -828,11 +827,22 @@ governed by {§canonical-statement}; runtime conditions remain explicit below.
|
|
|
828
827
|
| NOTE | none | none | literal working memory |
|
|
829
828
|
| WAIT | optional label ({§send-wait-scope}) | none; duration is `[seconds]` metadata | explanation of the wait |
|
|
830
829
|
|
|
830
|
+
§retrieval-annotation **A retrieval's authored body is memory, not selection or output.**
|
|
831
|
+
A nonblank body beneath FIND or READ becomes one ordinary NOTE immediately before
|
|
832
|
+
the retrieval, including a body consisting of a pattern or an HTML comment. A
|
|
833
|
+
grouped READ contributes one NOTE before its expanded statements. The retrieval
|
|
834
|
+
itself has no body; its selector comes only from its header. Normalization is the
|
|
835
|
+
same in content and exposed reasoning and never executes quoted body text. The
|
|
836
|
+
canonical rendering is NOTE followed by bodyless retrieval; exact submitted text
|
|
837
|
+
remains source evidence. The NOTE persists independently of retrieval success and
|
|
838
|
+
is curated normally. Explicit NOTE remains the taught form.
|
|
839
|
+
|
|
831
840
|
§note-value NOTE retains its literal body as ordinary model-owned working memory.
|
|
832
841
|
It has no target, scope, metadata, or lifecycle effect. Its full body participates
|
|
833
842
|
in ordinary log token accounting and model-driven curation; prior notes are not
|
|
834
|
-
automatically hidden.
|
|
835
|
-
|
|
843
|
+
automatically hidden. Each turn may contain zero or more NOTEs; their omission
|
|
844
|
+
produces neither a notice nor a failure. A NOTE-only turn does not request
|
|
845
|
+
completion; ordinary repetition and strike rules still apply.
|
|
836
846
|
|
|
837
847
|
§reasoning-operations The shared fence parser admits complete, line-leading NOTE,
|
|
838
848
|
FIND and READ statements from exposed provider reasoning. Admission is part of
|
|
@@ -856,9 +866,10 @@ reasoning operations contribute neither execution nor normalization notices.
|
|
|
856
866
|
|
|
857
867
|
§exec-executor-slot The fence name selects the executor directly: for example,
|
|
858
868
|
`python3 (tools/report.py)` or `gitea (issue_list)` on the opening fence line.
|
|
859
|
-
Reserved native OP names take precedence.
|
|
860
|
-
|
|
861
|
-
Registration is checked
|
|
869
|
+
Reserved native OP names take precedence. An executor heading's AST ({§executor-heading})
|
|
870
|
+
carries the `runtime` tag and no operation keyword, then `target`, metadata, timing and body fields.
|
|
871
|
+
Registration is checked at the invocation's execution point, after earlier operations settle
|
|
872
|
+
({§op-execution-order}), not by the syntax parser. An attached
|
|
862
873
|
MCP service uses that executor path and its owner validates the named tool and
|
|
863
874
|
input-body JSON against its schema. Unknown names do not fall back to a shell.
|
|
864
875
|
There is no runtime-less form: every execution names its runtime, and canonical
|
|
@@ -1094,8 +1105,7 @@ ingestion restriction: the parser decomposes arbitrary URL authorities.
|
|
|
1094
1105
|
## §matcher-prefix-claims 6. Bulk pattern matching
|
|
1095
1106
|
|
|
1096
1107
|
FIND, READ, KILL, EDIT, and the COPY/MOVE operands accept an optional matcher
|
|
1097
|
-
through the `pattern` option ({§matcher-option})
|
|
1098
|
-
carries its matcher as a body. AstBuilder assigns the dialect from the
|
|
1108
|
+
through the `pattern` option ({§matcher-option}). AstBuilder assigns the dialect from the
|
|
1099
1109
|
matcher's leading characters. A leading prefix claims its dialect. Invalid
|
|
1100
1110
|
claimed syntax never falls back to glob matching: it is the operation's own
|
|
1101
1111
|
refusal ({§matcher-refusal}), not a parse error.
|
|
@@ -1160,8 +1170,8 @@ statements remain recoverable when their boundaries are trustworthy.
|
|
|
1160
1170
|
|
|
1161
1171
|
- §pattern-body-single-line Every matcher is one physical line. On the protocol
|
|
1162
1172
|
operations it is the heading line's text ({§naked-pattern}) or the `pattern` option's
|
|
1163
|
-
JSON string ({§matcher-option})
|
|
1164
|
-
|
|
1173
|
+
JSON string ({§matcher-option}); AstBuilder rejects a multiline one before dialect
|
|
1174
|
+
classification. A regex that matches a
|
|
1165
1175
|
newline uses the two-character `\n` escape. Non-matcher operation bodies remain
|
|
1166
1176
|
multiline.
|
|
1167
1177
|
|
|
@@ -1178,7 +1188,7 @@ The operation column names the canonical AST operation after
|
|
|
1178
1188
|
| Operation | Canonical components | Meaning |
|
|
1179
1189
|
|-----------------------|----------------------------------------|----------------------------------------------------------------------------|
|
|
1180
1190
|
| FIND | 0–2 positions | Inclusive resource or exact-target location positions ({§find-result-unit}; markerless first page under {§markerless-first-page}) |
|
|
1181
|
-
| READ
|
|
1191
|
+
| READ | 0/1/2/4 text coordinates | Text projection from one exact selected file, entry, or log item |
|
|
1182
1192
|
| EDIT | 0/1/2/4 text coordinates | Text replacement, deletion, prepend, or append |
|
|
1183
1193
|
| COPY/MOVE source | 0/1/2/4 text coordinates | Region copied or moved from the selected source |
|
|
1184
1194
|
| COPY/MOVE destination | 0/1/2/4 text coordinates after target | Region replaced or insertion point at the destination |
|
|
@@ -1199,7 +1209,7 @@ body, while unsupported arity is a runtime failure.
|
|
|
1199
1209
|
spelled `@` followed by exactly five Base62 characters (`0-9A-Za-z`) wherever
|
|
1200
1210
|
its `L`, `SL`, or `EL` position denotes a line. Columns, prepend `0`, and append
|
|
1201
1211
|
`-1` remain numeric. Exact READ, EDIT, COPY/MOVE source and destination,
|
|
1202
|
-
|
|
1212
|
+
and KILL preserve these positions in `TextLineMarker`; core resolves them
|
|
1203
1213
|
against the addressed current text before operation-specific numeric scope
|
|
1204
1214
|
semantics run. FIND's result positions remain numeric and reject anchors. Numeric text scopes remain
|
|
1205
1215
|
canonical and fully supported. Parser acceptance does not imply model-facing
|
|
@@ -1386,8 +1396,8 @@ reports how many recorded turns concluded in a way the current contract would re
|
|
|
1386
1396
|
|
|
1387
1397
|
## 12. Public API
|
|
1388
1398
|
|
|
1389
|
-
The package root is the single JavaScript and TypeScript entry point
|
|
1390
|
-
and wire types come from generated schemas; the small hand-maintained parser
|
|
1399
|
+
The package root is the single JavaScript and TypeScript entry point for the language and wire
|
|
1400
|
+
contracts ({§runtime-neutral-root}). Shared AST and wire types come from generated schemas; the small hand-maintained parser
|
|
1391
1401
|
types cover ordered parse items and `PlurnkParseError`, which JSON Schema cannot
|
|
1392
1402
|
express. Consumers never receive ANTLR parse-tree or token types.
|
|
1393
1403
|
|
|
@@ -1415,7 +1425,6 @@ blocks themselves are the program.
|
|
|
1415
1425
|
|--------------------------------|----------------------------------------------------------------|-----------------------|
|
|
1416
1426
|
| `PlurnkParser.parse` | One model turn, including recoverable outside text and operation diagnostics | `PlurnkStatement` |
|
|
1417
1427
|
| `PlurnkParser.parseStatements` | Zero or more protocol statements | `PlurnkStatement` |
|
|
1418
|
-
| `PlurnkParser.parseClient` | Executable blocks, including the read-shaped LOOK command | `ClientStatement` |
|
|
1419
1428
|
|
|
1420
1429
|
Every entry point returns ordered `statement` and `error` items. The model-turn
|
|
1421
1430
|
entry point also returns `text` items under {§response-text}. When present,
|
|
@@ -1423,6 +1432,14 @@ entry point also returns `text` items under {§response-text}. When present,
|
|
|
1423
1432
|
extent. The statement `op` field discriminates the generated per-operation
|
|
1424
1433
|
union.
|
|
1425
1434
|
|
|
1435
|
+
§runtime-neutral-root **The package root is runtime-neutral.** A browser type-checks it with DOM
|
|
1436
|
+
libraries and no Node globals: nothing it reaches names a Node module or global. The application port
|
|
1437
|
+
({§application-port}), whose HTTP host hands an adapter Node's request and response ({§http-host}), is
|
|
1438
|
+
the one Node-bound contract and its own types-only entry, `@plurnk/plurnk-contracts/port`, with
|
|
1439
|
+
`HttpHost` and `HttpRouteHandler`; the types it speaks stay in the root. A helper that reads a request
|
|
1440
|
+
takes only its headers (`RequestHeaders`), which a Node request satisfies. Lint checks the root's whole
|
|
1441
|
+
source graph under those settings (`tsconfig.browser.json`).
|
|
1442
|
+
|
|
1426
1443
|
§root-value-api The package-root runtime namespace is closed. Its exact membership has one home,
|
|
1427
1444
|
`src/index.test.ts`, which fails on any addition or removal; the table names the families and
|
|
1428
1445
|
their owners. All other root exports are TypeScript types. `PlurnkParser` and `parsePath` are not
|
|
@@ -1443,8 +1460,8 @@ among them: the parser is `@plurnk/plurnk-parser`'s ({§parser-consumers}).
|
|
|
1443
1460
|
|
|
1444
1461
|
The remaining values are small pure helpers over those contracts (`isExecution`, `writtenOp`,
|
|
1445
1462
|
`lifecycleOfLoopStatus`, `selectWorkerLoop`, `renderJsonResult`, `formatJsonDocument`,
|
|
1446
|
-
`aguiConformanceReport`) and the closed name patterns
|
|
1447
|
-
`SKILL_NAME`, `EFFORTS`).
|
|
1463
|
+
`aguiConformanceReport`, `requestOrigin` for {§http-request-origin}) and the closed name patterns
|
|
1464
|
+
and vocabularies (`RUNTIME_TAG`, `SKILL_NAME`, `EFFORTS`).
|
|
1448
1465
|
|
|
1449
1466
|
§parser-construction-boundary Parser construction components are internal rather
|
|
1450
1467
|
than alternate consumer entry points:
|
|
@@ -1678,7 +1695,8 @@ authority, and optional local `cardPath`, `headers`, and bearer
|
|
|
1678
1695
|
|
|
1679
1696
|
`ApplicationPort` is the single transport-neutral TypeScript contract through
|
|
1680
1697
|
which an exterior adapter drives and observes the Plurnk application. Core
|
|
1681
|
-
implements it; AG-UI, A2A, and other interface modules consume it
|
|
1698
|
+
implements it; AG-UI, A2A, and other interface modules consume it from
|
|
1699
|
+
`@plurnk/plurnk-contracts/port` ({§runtime-neutral-root}). The port
|
|
1682
1700
|
contains typed application calls and a scoped event subscription, not wire
|
|
1683
1701
|
route names, protocol framing, persistence access, or adapter-specific methods.
|
|
1684
1702
|
An exterior adapter owns its own protocol validation, identity binding, and
|
|
@@ -1700,13 +1718,13 @@ it; Core validates and records it through the same prompt admission path.
|
|
|
1700
1718
|
`runLoop.attachments` carries typed bytes selected by the adapter;
|
|
1701
1719
|
`runLoop.envelope` retains opaque protocol evidence under
|
|
1702
1720
|
{§message-envelope-evidence}. `readMessages` projects durable inbox messages
|
|
1703
|
-
and successful
|
|
1721
|
+
and successful replies independently of log visibility, retaining
|
|
1704
1722
|
each reply's `answers` addresses (empty for incoming messages).
|
|
1705
1723
|
`resolveClientInteraction` may carry the accepted answer's message evidence;
|
|
1706
1724
|
Core validates the resolution, retains the arrival, then resumes the operation.
|
|
1707
1725
|
|
|
1708
1726
|
§application-worker-observation Worker observation exposes durable identity,
|
|
1709
|
-
origin, immediate parent identity, minted `kind` (`
|
|
1727
|
+
origin, immediate parent identity, minted `kind` (`root` for a worker with no parent; `fork` for a
|
|
1710
1728
|
child carrying a fork boundary; `work` for any other child), and `lifecycle`,
|
|
1711
1729
|
the worker's representative work loop projected through {§loop-lifecycle-vocabulary} (`idle`
|
|
1712
1730
|
when it has none). `selectWorkerLoop` chooses running before parked before queued;
|
|
@@ -1729,7 +1747,11 @@ in `@plurnk/plurnk-contracts` is that projection's one owner.
|
|
|
1729
1747
|
|
|
1730
1748
|
§application-loop-observation Loop observation exposes the durable scheduler
|
|
1731
1749
|
state of work loops (excluding maintenance-only administrative loops), nullable
|
|
1732
|
-
`waitUntil` (the durable observation deadline in Unix milliseconds),
|
|
1750
|
+
`waitUntil` (the durable observation deadline in Unix milliseconds), the times a loop first
|
|
1751
|
+
ran (`claimedAt`, {§loop-claim-latency}) and concluded (`terminatedAt`), ISO 8601 UTC and null
|
|
1752
|
+
until they happen, exact terminal `OperationResult`, the operation that opened the loop
|
|
1753
|
+
(`invocation`: its Worker and log address, {§worker-obligations}; null when no Worker's operation did),
|
|
1754
|
+
and exact count of packet-bearing
|
|
1733
1755
|
Turns for one owned Worker. Packetless producer Turns and physical provider
|
|
1734
1756
|
retries do not contribute to `packetCount`. Exterior
|
|
1735
1757
|
adapters consume this projection instead of reconstructing lifecycle from
|
|
@@ -1756,15 +1778,15 @@ class PlurnkParseError extends Error {
|
|
|
1756
1778
|
```
|
|
1757
1779
|
|
|
1758
1780
|
§parse-admission **A diagnostic's severity does not describe whether an operation ran.**
|
|
1759
|
-
`operationOmitted` identifies unexecuted unfenced operations
|
|
1760
|
-
|
|
1781
|
+
`operationOmitted` identifies unexecuted unfenced operations and unrecovered native
|
|
1782
|
+
calls. A warning about a retained operation or a quoted
|
|
1761
1783
|
example does not set it. This fact survives serialization when true; consumers do
|
|
1762
1784
|
not infer it from diagnostic wording. It does not independently prescribe a strike.
|
|
1763
1785
|
|
|
1764
1786
|
§parse-recovery **Every hard diagnostic carries its working form.** A `severity: "error"`
|
|
1765
1787
|
diagnostic names, in `recovery`, the form of the construct it refused, in the model's terms: a
|
|
1766
1788
|
refused heading carries the operation's canonical line (`` `READ (path) <L,M>? pattern? <!-- aside -->?`
|
|
1767
|
-
on the opening fence line
|
|
1789
|
+
on the opening fence line. ``), a refused scope the scope's form, and a refused
|
|
1768
1790
|
matcher its dialect's form with an example (`` A pattern is a regex written `/pattern/flags`, such
|
|
1769
1791
|
as `/timeout/i`. ``). The working form is the language's, never a reconstruction of the input
|
|
1770
1792
|
({§diagnostic-observation}). The runtime projects `recovery` as the Problem's `recovery` beside the
|
|
@@ -1853,7 +1875,7 @@ diagnostics are:
|
|
|
1853
1875
|
that already names a channel keeps such a token as its pattern. Those
|
|
1854
1876
|
matchers remain independent of owner options: a block without `pattern` never
|
|
1855
1877
|
erases the heading matcher, and invalid blocks still reach the owning validator.
|
|
1856
|
-
|
|
1878
|
+
Their heading-line text owns selection independently of annotation or distillation bodies. On EDIT only
|
|
1857
1879
|
a sigil lifts, because plain heading-line text is the replacement body it always
|
|
1858
1880
|
was; the lines beneath the heading are then the replacement, and none deletes each
|
|
1859
1881
|
match ({§edit-pattern}). A trailing `<!-- aside -->` on the same line stays the
|
|
@@ -1914,15 +1936,12 @@ diagnostics are:
|
|
|
1914
1936
|
body instead, the anchor would be written into the file, or the EDIT refused for want of a line
|
|
1915
1937
|
marker (14 distinct recorded headings). On READ and KILL the same text stays a literal matcher,
|
|
1916
1938
|
since `@patch` is a search a model means.
|
|
1917
|
-
- §matcher-body-redirect **Unread
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
{§
|
|
1923
|
-
One sigil line beneath a bodyless heading is the bare form written a line low and still lifts;
|
|
1924
|
-
nothing else is promoted into a matcher from below the heading. An option block's `pattern`
|
|
1925
|
-
prevents that lift, and the advisory never echoes the discarded text.
|
|
1939
|
+
- §matcher-body-redirect **Unread selector text.** An option block's `pattern` owns the
|
|
1940
|
+
selector; surplus heading text is unused with one warning naming its location.
|
|
1941
|
+
A non-log KILL's body is likewise unused: `This KILL takes no body; line 2 was not used.`
|
|
1942
|
+
Neither warning echoes discarded text. No operation recovers a matcher from below
|
|
1943
|
+
its header. READ/FIND bodies follow {§retrieval-annotation}; log KILL bodies follow
|
|
1944
|
+
{§log-kill-distillation}.
|
|
1926
1945
|
- §combined-anchor-tolerance **Combined line number and anchor in a scope.** A
|
|
1927
1946
|
text-coordinate scope written `L<@hash>` — digits immediately before the opener — is the
|
|
1928
1947
|
displayed `42<@abcde>` row prefix copied whole: the scope is the anchor, the number is dropped, and one
|
|
@@ -1938,15 +1957,6 @@ diagnostics are:
|
|
|
1938
1957
|
states the anchor rule instead, with the scope marked: `` every line anchor carries
|
|
1939
1958
|
its `@`: `<@abcde,@fghij>` ``. Spacing and boundary-loss diagnostics retain their own
|
|
1940
1959
|
contracts.
|
|
1941
|
-
- §misplaced-aside-advisory **Aside in the body.** A READ or FIND whose
|
|
1942
|
-
body is solely an HTML comment (`<!-- … -->`) can never carry a matcher: it is
|
|
1943
|
-
the aside the model put on the line below the heading. The builder takes
|
|
1944
|
-
the comment as the aside when the heading has none, builds the operation
|
|
1945
|
-
with no body, and raises one warning-severity advisory stating that observed
|
|
1946
|
-
normalization; the parser places the advisory right after its statement and
|
|
1947
|
-
the service delivers it as a `parse_advisory` notice with its position. A body
|
|
1948
|
-
with any other content is ignored under the same advisory path
|
|
1949
|
-
({§matcher-body-redirect}).
|
|
1950
1960
|
|
|
1951
1961
|
§error-shape The diagnostic class determines the parts of a message; every class says what
|
|
1952
1962
|
happened, never why ({§diagnostic-observation}). Advisories belong to one successfully built statement. A rejected
|
|
@@ -1969,6 +1979,11 @@ intent ({§diagnostic-observation}).
|
|
|
1969
1979
|
Unexpected top-level text immediately after a closed operation identifies that
|
|
1970
1980
|
operation's opening line, closing line, and matching backtick count.
|
|
1971
1981
|
|
|
1982
|
+
§parse-attempt A hard fact that refused a statement the parser opened carries its `attempt`: the
|
|
1983
|
+
statement's text exactly as written, from its opening fence as far as the parser read it, and the
|
|
1984
|
+
`verb` that fence names, an operation keyword or an execution's runtime tag. A diagnostic that refused no opened
|
|
1985
|
+
statement, such as a lost boundary or a stray character outside every statement, carries none.
|
|
1986
|
+
|
|
1972
1987
|
Examples of canonical hard facts:
|
|
1973
1988
|
|
|
1974
1989
|
- `unrecognized character '<' in target`
|