@kottera/tera-web 0.1.0-rc.2 → 0.1.0-rc.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/README.md +3 -2
- package/dist/client.d.ts +59 -5
- package/dist/client.js +203 -16
- package/dist/feed/connection.d.ts +2 -0
- package/dist/feed/connection.js +2 -2
- package/dist/generated/kit.d.ts +61 -6
- package/dist/generated/kit.js +24 -4
- package/dist/generated/shares.d.ts +196 -0
- package/dist/generated/shares.js +17 -0
- package/dist/generated/workorder-events.d.ts +1 -1
- package/dist/generated/workorder.d.ts +91 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -1
- package/dist/routes.d.ts +15 -0
- package/dist/routes.js +28 -0
- package/dist/stepup.d.ts +87 -0
- package/dist/stepup.js +66 -0
- package/package.json +1 -1
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An ended share.
|
|
3
|
+
*
|
|
4
|
+
* The result of api.v1.shares.delete and api.v1.shares.leave: what the act ended. An ended share decides nothing and is not listed.
|
|
5
|
+
*
|
|
6
|
+
* Schema: sdk/shares/schema/v1/ended.json
|
|
7
|
+
*/
|
|
8
|
+
export type SharesEnded = {
|
|
9
|
+
/** The ended share's id. */
|
|
10
|
+
id: string;
|
|
11
|
+
/** The installation whose resource was shared, <vault>/plugins/<installation>. */
|
|
12
|
+
installation: string;
|
|
13
|
+
/** The resource that was shared. */
|
|
14
|
+
resource: string;
|
|
15
|
+
/** The grantee person's id. */
|
|
16
|
+
grantee: string;
|
|
17
|
+
/** The sharer person's id. */
|
|
18
|
+
sharer: string;
|
|
19
|
+
/** How the share ended, as its record holds it: revoked or left. */
|
|
20
|
+
ended: "revoked" | "left";
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Extend a share.
|
|
24
|
+
*
|
|
25
|
+
* The params of api.v1.shares.patch, PATCH /api/v1/shares/{id} (ADR-174 D11).
|
|
26
|
+
*
|
|
27
|
+
* Schema: sdk/shares/schema/v1/extend.request.json
|
|
28
|
+
*/
|
|
29
|
+
export type SharesExtendRequest = {
|
|
30
|
+
/** The share's id, a UUIDv7. */
|
|
31
|
+
id: string;
|
|
32
|
+
/** The new expiry: later than the share's, at most the installation's max_expiry from now. Absent takes the kind's default_expiry from now, clamped to max_expiry. */
|
|
33
|
+
expires_at?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Name one share.
|
|
37
|
+
*
|
|
38
|
+
* The params of api.v1.shares.get, api.v1.shares.delete and api.v1.shares.leave: the {id} of /api/v1/shares/{id}.
|
|
39
|
+
*
|
|
40
|
+
* Schema: sdk/shares/schema/v1/id.request.json
|
|
41
|
+
*/
|
|
42
|
+
export type SharesIdRequest = {
|
|
43
|
+
/** The share's id, a UUIDv7. */
|
|
44
|
+
id: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A list of shares.
|
|
48
|
+
*
|
|
49
|
+
* The result of api.v1.shares.list.
|
|
50
|
+
*
|
|
51
|
+
* Schema: sdk/shares/schema/v1/list.json
|
|
52
|
+
*/
|
|
53
|
+
export type SharesList = {
|
|
54
|
+
/** The shares, each with whether it decides now. */
|
|
55
|
+
shares: {
|
|
56
|
+
/** The share's id, a UUIDv7. */
|
|
57
|
+
id: string;
|
|
58
|
+
/** The installation whose resource is shared, <vault>/plugins/<installation>. */
|
|
59
|
+
installation: string;
|
|
60
|
+
/** The resource shared, plugins/<vault>/<installation>/<kind>/<id>. */
|
|
61
|
+
resource: string;
|
|
62
|
+
/** The shared verbs. */
|
|
63
|
+
verbs: string[] | null;
|
|
64
|
+
/** What the grantee is: person. */
|
|
65
|
+
grantee_kind: string;
|
|
66
|
+
/** The grantee person's id. */
|
|
67
|
+
grantee: string;
|
|
68
|
+
/** The id of the person who made the share. */
|
|
69
|
+
sharer: string;
|
|
70
|
+
/** The plugin principal that made the share for its sharer; absent when the sharer made it directly. */
|
|
71
|
+
created_via?: string;
|
|
72
|
+
/** When the share was made. */
|
|
73
|
+
created_at: string;
|
|
74
|
+
/** When the share stops deciding. */
|
|
75
|
+
expires_at: string;
|
|
76
|
+
/** When the share was last extended; absent if never. */
|
|
77
|
+
extended_at?: string;
|
|
78
|
+
/** Whether the share decides at least one of its verbs on the grantee's next request, computed from what decides now. */
|
|
79
|
+
deciding: boolean;
|
|
80
|
+
/** When deciding is false, the one reason why. Absent while the share decides. */
|
|
81
|
+
not_deciding?: "sharer_lost_access" | "sharing_disabled" | "installation_not_standing" | "verb_no_longer_shareable" | "pending_invitation";
|
|
82
|
+
}[] | null;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* List shares.
|
|
86
|
+
*
|
|
87
|
+
* The params of api.v1.shares.list, the query of GET /api/v1/shares. At most one member is named; with none, the caller's own live shares as grantee and as sharer.
|
|
88
|
+
*
|
|
89
|
+
* Schema: sdk/shares/schema/v1/list.request.json
|
|
90
|
+
*/
|
|
91
|
+
export type SharesListRequest = {
|
|
92
|
+
/** An installation, <vault>/plugins/<name>: every share on it. Needs the shares admin grant (api/v1/shares/admin). */
|
|
93
|
+
installation?: string;
|
|
94
|
+
/** One resource, plugins/<vault>/<installation>/<kind>/<id>: every share on it when the caller's own grants include its share-conferring verb, else the caller's own shares on it. */
|
|
95
|
+
resource?: string;
|
|
96
|
+
/** A grantee's person id; someone else's needs the shares admin grant. */
|
|
97
|
+
grantee?: string;
|
|
98
|
+
/** A sharer's person id; someone else's needs the shares admin grant. */
|
|
99
|
+
sharer?: string;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Make a share.
|
|
103
|
+
*
|
|
104
|
+
* The params of api.v1.shares.create, the body of POST /api/v1/shares (ADR-174 D6).
|
|
105
|
+
*
|
|
106
|
+
* Schema: sdk/shares/schema/v1/make.request.json
|
|
107
|
+
*/
|
|
108
|
+
export type SharesMakeRequest = {
|
|
109
|
+
/** The one resource shared, plugins/<vault>/<installation>/<kind>/<id>. */
|
|
110
|
+
resource: string;
|
|
111
|
+
/** The shared verbs: a non-empty subset of the kind's sharing { verbs }, never its share-conferring verb. */
|
|
112
|
+
verbs: string[];
|
|
113
|
+
/** The grantee person's id. Exactly one of grantee and grantee_address names the grantee. */
|
|
114
|
+
grantee?: string;
|
|
115
|
+
/** An email address the directory resolves to the grantee. An address no person holds is invited, and the share is pending until they sign in, on a kind whose effective grantee class is addresses; otherwise it is refused share_grantee_not_admitted. */
|
|
116
|
+
grantee_address?: string;
|
|
117
|
+
/** The share's expiry, at most the installation's max_expiry from now. Absent takes the kind's default_expiry, clamped to max_expiry. */
|
|
118
|
+
expires_at?: string;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* The vocabulary of the share acts' refusal codes (sdk/shares.Codes).
|
|
122
|
+
*
|
|
123
|
+
* Every stable code a share act is refused with. A code is never renamed; a new refusal is a new code, so a reader keeps a code it does not know as it arrived. share_not_found answers a share the caller may not see exactly as an id no share has. share_grantee_not_admitted answers an address no person holds on a kind whose effective grantee class is not addresses; on one that is, the address is invited and the share is pending until the invitee signs in.
|
|
124
|
+
*
|
|
125
|
+
* Schema: sdk/shares/schema/v1/refusal-code.json
|
|
126
|
+
*/
|
|
127
|
+
export type SharesRefusalCode = "share_sharer_not_a_person" | "share_sharing_disabled" | "share_resource_not_shareable" | "share_resource_unknown" | "share_actor_other_installation" | "share_verb_not_shareable" | "share_verb_confers_sharing" | "share_verb_not_held" | "share_grantee_not_admitted" | "share_guest_cannot_invite" | "share_invitation_refused" | "share_grantee_is_sharer" | "share_expiry_beyond_max" | "share_cap_active" | "share_cap_pending_invitations" | "share_exists" | "share_caller_not_a_person" | "share_not_found" | "share_sharer_lost_access" | "share_expiry_not_later" | "share_admin_required" | "share_list_query" | "shares_unavailable";
|
|
128
|
+
/**
|
|
129
|
+
* A share act refused.
|
|
130
|
+
*
|
|
131
|
+
* A share act tera refused, as the shares client answers it: the route's stable code and its words, unchanged, and the detail the code declares.
|
|
132
|
+
*
|
|
133
|
+
* Schema: sdk/shares/schema/v1/refusal.json
|
|
134
|
+
*/
|
|
135
|
+
export type SharesRefusal = {
|
|
136
|
+
/** The route's stable code. A code a reader does not know is kept as it arrived. */
|
|
137
|
+
code: string;
|
|
138
|
+
/** The route's words for a person, unchanged. */
|
|
139
|
+
message: string;
|
|
140
|
+
/** On share_verb_not_held, share_verb_not_shareable and share_verb_confers_sharing, the verb refused. */
|
|
141
|
+
verb?: string;
|
|
142
|
+
/** On share_exists, the id of the share already there. */
|
|
143
|
+
existing?: string;
|
|
144
|
+
/** On share_invitation_refused, why the address was not invited (inviter_limited, email_unavailable, ...). */
|
|
145
|
+
invitation?: string;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* A share.
|
|
149
|
+
*
|
|
150
|
+
* One live share, with whether it decides now: the result of api.v1.shares.create, api.v1.shares.get and api.v1.shares.patch, and each member of a list (ADR-174 D14).
|
|
151
|
+
*
|
|
152
|
+
* Schema: sdk/shares/schema/v1/share.json
|
|
153
|
+
*/
|
|
154
|
+
export type SharesShare = {
|
|
155
|
+
/** The share's id, a UUIDv7. */
|
|
156
|
+
id: string;
|
|
157
|
+
/** The installation whose resource is shared, <vault>/plugins/<installation>. */
|
|
158
|
+
installation: string;
|
|
159
|
+
/** The resource shared, plugins/<vault>/<installation>/<kind>/<id>. */
|
|
160
|
+
resource: string;
|
|
161
|
+
/** The shared verbs. */
|
|
162
|
+
verbs: string[] | null;
|
|
163
|
+
/** What the grantee is: person. */
|
|
164
|
+
grantee_kind: string;
|
|
165
|
+
/** The grantee person's id. */
|
|
166
|
+
grantee: string;
|
|
167
|
+
/** The id of the person who made the share. */
|
|
168
|
+
sharer: string;
|
|
169
|
+
/** The plugin principal that made the share for its sharer; absent when the sharer made it directly. */
|
|
170
|
+
created_via?: string;
|
|
171
|
+
/** When the share was made. */
|
|
172
|
+
created_at: string;
|
|
173
|
+
/** When the share stops deciding. */
|
|
174
|
+
expires_at: string;
|
|
175
|
+
/** When the share was last extended; absent if never. */
|
|
176
|
+
extended_at?: string;
|
|
177
|
+
/** Whether the share decides at least one of its verbs on the grantee's next request, computed from what decides now. */
|
|
178
|
+
deciding: boolean;
|
|
179
|
+
/** When deciding is false, the one reason why. Absent while the share decides. */
|
|
180
|
+
not_deciding?: "sharer_lost_access" | "sharing_disabled" | "installation_not_standing" | "verb_no_longer_shareable" | "pending_invitation";
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Every type this module declares, mapped to the repository path of the schema
|
|
184
|
+
* it was generated from.
|
|
185
|
+
*/
|
|
186
|
+
export declare const SHARES_SCHEMAS: {
|
|
187
|
+
readonly SharesEnded: "sdk/shares/schema/v1/ended.json";
|
|
188
|
+
readonly SharesExtendRequest: "sdk/shares/schema/v1/extend.request.json";
|
|
189
|
+
readonly SharesIdRequest: "sdk/shares/schema/v1/id.request.json";
|
|
190
|
+
readonly SharesList: "sdk/shares/schema/v1/list.json";
|
|
191
|
+
readonly SharesListRequest: "sdk/shares/schema/v1/list.request.json";
|
|
192
|
+
readonly SharesMakeRequest: "sdk/shares/schema/v1/make.request.json";
|
|
193
|
+
readonly SharesRefusalCode: "sdk/shares/schema/v1/refusal-code.json";
|
|
194
|
+
readonly SharesRefusal: "sdk/shares/schema/v1/refusal.json";
|
|
195
|
+
readonly SharesShare: "sdk/shares/schema/v1/share.json";
|
|
196
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Code generated by cmd/internal/genwebtypes from sdk/shares/schema/v1/; DO NOT EDIT.
|
|
2
|
+
// Regenerate with `make web-types` (ADR-162 D4 item 1).
|
|
3
|
+
/**
|
|
4
|
+
* Every type this module declares, mapped to the repository path of the schema
|
|
5
|
+
* it was generated from.
|
|
6
|
+
*/
|
|
7
|
+
export const SHARES_SCHEMAS = {
|
|
8
|
+
SharesEnded: "sdk/shares/schema/v1/ended.json",
|
|
9
|
+
SharesExtendRequest: "sdk/shares/schema/v1/extend.request.json",
|
|
10
|
+
SharesIdRequest: "sdk/shares/schema/v1/id.request.json",
|
|
11
|
+
SharesList: "sdk/shares/schema/v1/list.json",
|
|
12
|
+
SharesListRequest: "sdk/shares/schema/v1/list.request.json",
|
|
13
|
+
SharesMakeRequest: "sdk/shares/schema/v1/make.request.json",
|
|
14
|
+
SharesRefusalCode: "sdk/shares/schema/v1/refusal-code.json",
|
|
15
|
+
SharesRefusal: "sdk/shares/schema/v1/refusal.json",
|
|
16
|
+
SharesShare: "sdk/shares/schema/v1/share.json",
|
|
17
|
+
};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Schema: sdk/workorder/schema/events/v1/event-kind.workorder.json
|
|
7
7
|
*/
|
|
8
|
-
export type WorkOrderEventKind = "cohort.set" | "off_tera.wake" | "relation.set" | "relation.removed" | "off_tera.taken" | "off_tera.progress" | "off_tera.reposted" | "off_tera.late_report" | "off_tera.checks_started" | "created" | "transitioned" | "acknowledged" | "retention_expired" | "edited" | "seat.reclaimed" | "claim.overdue" | "claim.unreadable" | "subject_claim.overridden" | "seat.cooling" | "seat.credential_held" | "member_credential.requested" | "member_credential.settled" | "seat.acquired" | "seat.runner_released" | "seat.meters_voided" | "step.binding" | "session.terminated" | "postcondition.verdict" | "parked_run.unreadable" | "parked_run.reclaimed" | "dispatch.settled_unobserved" | "parked_run.parked" | "parked_run.resumed" | "resume.refused" | "dispatch.salvaged" | "workspace.retired" | "dispatch.routed" | "session.lost" | "activity_partition.pinned" | "session.continuity" | "session.context_compacted" | "upstream.answer_forwarded" | "invocation.checkpoint" | "invocation.guidance" | "invocation.guidance.ack" | "invocation.reply" | "invocation.checkpoint.unreadable" | "invocation.guidance.unreadable" | "config_pin.unreadable" | "config_pin.repinned" | "type.followed" | "observation.scrubbed" | "observation.secret-shape-redacted" | "observation.promoted" | "observation.refuted" | "observation.purged" | "conversation.input_barrier" | "walk_resume.fell_back" | "store.ahead_of_binary" | "artifact.published" | "history.dropped" | "history.archived" | "seat.work_order_released" | "step.settled_late" | "step.reattached" | "relay.unrebuilt";
|
|
8
|
+
export type WorkOrderEventKind = "cohort.set" | "off_tera.wake" | "relation.set" | "relation.removed" | "off_tera.taken" | "off_tera.progress" | "off_tera.reposted" | "off_tera.late_report" | "off_tera.checks_started" | "created" | "transitioned" | "acknowledged" | "retention_expired" | "edited" | "seat.reclaimed" | "claim.overdue" | "claim.unreadable" | "subject_claim.overridden" | "seat.cooling" | "seat.credential_held" | "member_credential.requested" | "member_credential.settled" | "seat.acquired" | "seat.runner_released" | "seat.meters_voided" | "step.binding" | "session.terminated" | "postcondition.verdict" | "parked_run.unreadable" | "parked_run.reclaimed" | "dispatch.settled_unobserved" | "parked_run.parked" | "parked_run.resumed" | "resume.refused" | "dispatch.salvaged" | "workspace.retired" | "dispatch.routed" | "session.lost" | "activity_partition.pinned" | "session.continuity" | "session.context_compacted" | "upstream.answer_forwarded" | "invocation.checkpoint" | "invocation.guidance" | "invocation.guidance.ack" | "invocation.reply" | "invocation.checkpoint.unreadable" | "invocation.guidance.unreadable" | "config_pin.unreadable" | "config_pin.repinned" | "type.followed" | "observation.scrubbed" | "observation.secret-shape-redacted" | "observation.promoted" | "observation.refuted" | "observation.purged" | "conversation.input_barrier" | "walk_resume.fell_back" | "store.ahead_of_binary" | "artifact.published" | "history.dropped" | "history.archived" | "seat.work_order_released" | "step.settled_late" | "step.reattached" | "relay.unrebuilt" | "references.recorded";
|
|
9
9
|
/**
|
|
10
10
|
* `workorder` event payload (event/workorder).
|
|
11
11
|
*
|
|
@@ -48,6 +48,8 @@ export type WorkOrderAnswerParams = {
|
|
|
48
48
|
replace?: boolean;
|
|
49
49
|
/** Cross ONE refusal: a select site where this Work Order's live step binding is running a candidate the new pin no longer offers (ADR-130 D5, ratified crossable 2026-09-20). The binding row is RETAINED at the same chain generation and the resume RE-SELECTS from the new candidate set, running the candidate loop against live capacity exactly as a first admission would. It does NOT preserve the candidate the run is on — that candidate is gone, which is why the refusal exists. It lifts nothing else: a capability or operation switch at a fixed site has no candidate to re-select, and a withdrawn `yields_turn` offer is frozen for the life of a pinned conversation (ADR-129 D9). Over a site whose candidate IS still offered, or a fixed site, it is a no-op and says so in the manifest rather than refusing. Only meaningful with `repin`. Authorized against `api/v1/workorders/repin/reselect` IN ADDITION to `api/v1/workorders/repin`. Pass `dry_run` first: the manifest's `would_reselect` names the site, the candidate being given up and the set the resume will choose from. */
|
|
50
50
|
reselect?: boolean;
|
|
51
|
+
/** The id of the step-up a person confirmed this act with, when the Work Order's type requires one for it (ADR-173 D10): a review verdict, an answer, or an off-tera `complete` / `failed`. Call WITHOUT it first: the call is refused `step_up_required` and its error data names the step-up's `id` and the `url` the person opens to confirm it — show them that url; you cannot confirm it yourself. Then retry the IDENTICAL call with step_up = that id. `step_up_pending` means they have not confirmed yet: wait and retry the same call. A step-up confirms exactly one act with exactly this content, once. */
|
|
52
|
+
step_up?: string;
|
|
51
53
|
/** The operator's exact prose. Interactive answers become one durable ledger message; other answers are wrapped as {"answer": "<text>"}. Ignored when `payload` is supplied. */
|
|
52
54
|
text?: string;
|
|
53
55
|
};
|
|
@@ -965,6 +967,13 @@ export type WorkOrderGetResult = {
|
|
|
965
967
|
authorized_for?: string;
|
|
966
968
|
plugin?: string;
|
|
967
969
|
evidence_class?: string;
|
|
970
|
+
step_up?: {
|
|
971
|
+
id: string;
|
|
972
|
+
method: string;
|
|
973
|
+
anchor?: string;
|
|
974
|
+
at: string;
|
|
975
|
+
};
|
|
976
|
+
display_name?: string;
|
|
968
977
|
};
|
|
969
978
|
};
|
|
970
979
|
question?: {
|
|
@@ -1166,6 +1175,18 @@ export type WorkOrderGetResult = {
|
|
|
1166
1175
|
observed_at: string;
|
|
1167
1176
|
volumes?: string[];
|
|
1168
1177
|
};
|
|
1178
|
+
references?: {
|
|
1179
|
+
entries: {
|
|
1180
|
+
name: string;
|
|
1181
|
+
source: string;
|
|
1182
|
+
repository?: string;
|
|
1183
|
+
canonical_repository?: string;
|
|
1184
|
+
ref?: string;
|
|
1185
|
+
commit?: string;
|
|
1186
|
+
history?: boolean;
|
|
1187
|
+
}[] | null;
|
|
1188
|
+
recorded_at: string;
|
|
1189
|
+
};
|
|
1169
1190
|
execution?: {
|
|
1170
1191
|
waiter?: string;
|
|
1171
1192
|
runner?: string;
|
|
@@ -1205,10 +1226,22 @@ export type WorkOrderGetResult = {
|
|
|
1205
1226
|
describe?: string;
|
|
1206
1227
|
caller_is_person?: boolean;
|
|
1207
1228
|
outcome_provenance?: string;
|
|
1229
|
+
step_up?: {
|
|
1230
|
+
id: string;
|
|
1231
|
+
method: string;
|
|
1232
|
+
anchor?: string;
|
|
1233
|
+
at: string;
|
|
1234
|
+
};
|
|
1208
1235
|
};
|
|
1209
1236
|
outcome?: {
|
|
1210
1237
|
outcome_provenance: string;
|
|
1211
1238
|
attested_by?: string;
|
|
1239
|
+
step_up?: {
|
|
1240
|
+
id: string;
|
|
1241
|
+
method: string;
|
|
1242
|
+
anchor?: string;
|
|
1243
|
+
at: string;
|
|
1244
|
+
};
|
|
1212
1245
|
};
|
|
1213
1246
|
relations: {
|
|
1214
1247
|
relation: string;
|
|
@@ -1773,6 +1806,12 @@ export type WorkOrderListResult = {
|
|
|
1773
1806
|
describe?: string;
|
|
1774
1807
|
caller_is_person?: boolean;
|
|
1775
1808
|
outcome_provenance?: string;
|
|
1809
|
+
step_up?: {
|
|
1810
|
+
id: string;
|
|
1811
|
+
method: string;
|
|
1812
|
+
anchor?: string;
|
|
1813
|
+
at: string;
|
|
1814
|
+
};
|
|
1776
1815
|
};
|
|
1777
1816
|
}[] | null;
|
|
1778
1817
|
};
|
|
@@ -1806,6 +1845,12 @@ export type WorkOrderListOffTeraResult = {
|
|
|
1806
1845
|
describe?: string;
|
|
1807
1846
|
caller_is_person?: boolean;
|
|
1808
1847
|
outcome_provenance?: string;
|
|
1848
|
+
step_up?: {
|
|
1849
|
+
id: string;
|
|
1850
|
+
method: string;
|
|
1851
|
+
anchor?: string;
|
|
1852
|
+
at: string;
|
|
1853
|
+
};
|
|
1809
1854
|
};
|
|
1810
1855
|
take_age_seconds?: number;
|
|
1811
1856
|
/** On a held entry: the JSON Schema this Work Order was pinned to at its first take, which submit_result grades the record against. Absent on posted and taken entries, and when the type declares none. */
|
|
@@ -1828,6 +1873,12 @@ export type WorkOrderListOffTeraResult = {
|
|
|
1828
1873
|
describe?: string;
|
|
1829
1874
|
caller_is_person?: boolean;
|
|
1830
1875
|
outcome_provenance?: string;
|
|
1876
|
+
step_up?: {
|
|
1877
|
+
id: string;
|
|
1878
|
+
method: string;
|
|
1879
|
+
anchor?: string;
|
|
1880
|
+
at: string;
|
|
1881
|
+
};
|
|
1831
1882
|
};
|
|
1832
1883
|
take_age_seconds?: number;
|
|
1833
1884
|
/** On a held entry: the JSON Schema this Work Order was pinned to at its first take, which submit_result grades the record against. Absent on posted and taken entries, and when the type declares none. */
|
|
@@ -1850,6 +1901,12 @@ export type WorkOrderListOffTeraResult = {
|
|
|
1850
1901
|
describe?: string;
|
|
1851
1902
|
caller_is_person?: boolean;
|
|
1852
1903
|
outcome_provenance?: string;
|
|
1904
|
+
step_up?: {
|
|
1905
|
+
id: string;
|
|
1906
|
+
method: string;
|
|
1907
|
+
anchor?: string;
|
|
1908
|
+
at: string;
|
|
1909
|
+
};
|
|
1853
1910
|
};
|
|
1854
1911
|
take_age_seconds?: number;
|
|
1855
1912
|
/** On a held entry: the JSON Schema this Work Order was pinned to at its first take, which submit_result grades the record against. Absent on posted and taken entries, and when the type declares none. */
|
|
@@ -1950,6 +2007,12 @@ export type WorkOrderProgressResult = {
|
|
|
1950
2007
|
describe?: string;
|
|
1951
2008
|
caller_is_person?: boolean;
|
|
1952
2009
|
outcome_provenance?: string;
|
|
2010
|
+
step_up?: {
|
|
2011
|
+
id: string;
|
|
2012
|
+
method: string;
|
|
2013
|
+
anchor?: string;
|
|
2014
|
+
at: string;
|
|
2015
|
+
};
|
|
1953
2016
|
} | null;
|
|
1954
2017
|
addressed_events: {
|
|
1955
2018
|
id: number;
|
|
@@ -2538,6 +2601,8 @@ export type WorkOrderSubmitResultParams = {
|
|
|
2538
2601
|
};
|
|
2539
2602
|
/** The id of the last event you have processed on this Work Order. The response carries the events addressed to you after it (a repost, a cancel, a wake, an answer, posted guidance), at most 32 with `more` set when there were more, plus `newest_event_id`. The server keeps no cursor: omit it, or pass 0, for everything addressed so far. */
|
|
2540
2603
|
seen_through?: number;
|
|
2604
|
+
/** The id of the step-up a person confirmed this act with, when the Work Order's type requires one for it (ADR-173 D10): a review verdict, an answer, or an off-tera `complete` / `failed`. Call WITHOUT it first: the call is refused `step_up_required` and its error data names the step-up's `id` and the `url` the person opens to confirm it — show them that url; you cannot confirm it yourself. Then retry the IDENTICAL call with step_up = that id. `step_up_pending` means they have not confirmed yet: wait and retry the same call. A step-up confirms exactly one act with exactly this content, once. */
|
|
2605
|
+
step_up?: string;
|
|
2541
2606
|
};
|
|
2542
2607
|
/**
|
|
2543
2608
|
* `work_order.submit_result` result (v1).
|
|
@@ -2553,6 +2618,12 @@ export type WorkOrderSubmitResultResult = {
|
|
|
2553
2618
|
outcome?: {
|
|
2554
2619
|
outcome_provenance: string;
|
|
2555
2620
|
attested_by?: string;
|
|
2621
|
+
step_up?: {
|
|
2622
|
+
id: string;
|
|
2623
|
+
method: string;
|
|
2624
|
+
anchor?: string;
|
|
2625
|
+
at: string;
|
|
2626
|
+
};
|
|
2556
2627
|
};
|
|
2557
2628
|
checks?: string;
|
|
2558
2629
|
addressed_events: {
|
|
@@ -2600,6 +2671,12 @@ export type WorkOrderTakeResult = {
|
|
|
2600
2671
|
describe?: string;
|
|
2601
2672
|
caller_is_person?: boolean;
|
|
2602
2673
|
outcome_provenance?: string;
|
|
2674
|
+
step_up?: {
|
|
2675
|
+
id: string;
|
|
2676
|
+
method: string;
|
|
2677
|
+
anchor?: string;
|
|
2678
|
+
at: string;
|
|
2679
|
+
};
|
|
2603
2680
|
} | null;
|
|
2604
2681
|
instructions: string;
|
|
2605
2682
|
requirements?: string;
|
|
@@ -2663,6 +2740,8 @@ export type WorkOrderTransitionParams = {
|
|
|
2663
2740
|
replace?: boolean;
|
|
2664
2741
|
/** Cross ONE refusal: a select site where this Work Order's live step binding is running a candidate the new pin no longer offers (ADR-130 D5, ratified crossable 2026-09-20). The binding row is RETAINED at the same chain generation and the resume RE-SELECTS from the new candidate set, running the candidate loop against live capacity exactly as a first admission would. It does NOT preserve the candidate the run is on — that candidate is gone, which is why the refusal exists. It lifts nothing else: a capability or operation switch at a fixed site has no candidate to re-select, and a withdrawn `yields_turn` offer is frozen for the life of a pinned conversation (ADR-129 D9). Over a site whose candidate IS still offered, or a fixed site, it is a no-op and says so in the manifest rather than refusing. Only meaningful with `repin`. Authorized against `api/v1/workorders/repin/reselect` IN ADDITION to `api/v1/workorders/repin`. Pass `dry_run` first: the manifest's `would_reselect` names the site, the candidate being given up and the set the resume will choose from. */
|
|
2665
2742
|
reselect?: boolean;
|
|
2743
|
+
/** The id of the step-up a person confirmed this act with, when the Work Order's type requires one for it (ADR-173 D10): a review verdict, an answer, or an off-tera `complete` / `failed`. Call WITHOUT it first: the call is refused `step_up_required` and its error data names the step-up's `id` and the `url` the person opens to confirm it — show them that url; you cannot confirm it yourself. Then retry the IDENTICAL call with step_up = that id. `step_up_pending` means they have not confirmed yet: wait and retry the same call. A step-up confirms exactly one act with exactly this content, once. */
|
|
2744
|
+
step_up?: string;
|
|
2666
2745
|
/** action=answer only: the operator's answer text. Read work_order.get(id).question first — that is what is being asked. */
|
|
2667
2746
|
text?: string;
|
|
2668
2747
|
};
|
|
@@ -3090,6 +3169,12 @@ export type WorkOrderTreeResult = {
|
|
|
3090
3169
|
outcome?: {
|
|
3091
3170
|
outcome_provenance: string;
|
|
3092
3171
|
attested_by?: string;
|
|
3172
|
+
step_up?: {
|
|
3173
|
+
id: string;
|
|
3174
|
+
method: string;
|
|
3175
|
+
anchor?: string;
|
|
3176
|
+
at: string;
|
|
3177
|
+
};
|
|
3093
3178
|
};
|
|
3094
3179
|
replaced?: {
|
|
3095
3180
|
relation: string;
|
|
@@ -3314,6 +3399,12 @@ export type WorkOrderTreeResult = {
|
|
|
3314
3399
|
outcome?: {
|
|
3315
3400
|
outcome_provenance: string;
|
|
3316
3401
|
attested_by?: string;
|
|
3402
|
+
step_up?: {
|
|
3403
|
+
id: string;
|
|
3404
|
+
method: string;
|
|
3405
|
+
anchor?: string;
|
|
3406
|
+
at: string;
|
|
3407
|
+
};
|
|
3317
3408
|
};
|
|
3318
3409
|
replaced?: {
|
|
3319
3410
|
relation: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
export { ROUTE_PREFIX, routePath } from "./routes.ts";
|
|
1
|
+
export { ROOT_BASE, ROUTE_PREFIX, appBase, routePath, underBase } from "./routes.ts";
|
|
2
2
|
export { TeraClient, KitRequestError, UNRECOGNIZED_RESPONSE, type FeedOptions, type InvokeVerdict, type KitErrorBody, type TeraClientOptions, type UploadOptions, type UploadProgress, type UploadRequest, type VerbRefusal, } from "./client.ts";
|
|
3
|
+
export { STEP_UP_HEADER, STEP_UP_POLL_MS, STEP_UP_REQUIRED, STEP_UP_RESUME_PARAM, StepUpError, resumedStepUp, stepUpChallengeOf, stepUpPageURL, type StepUpChallenge, type StepUpEnd, type StepUpOptions, type StepUpWindow, } from "./stepup.ts";
|
|
3
4
|
export { BASE_DELAY_MS, MAX_DELAY_MS, REPLAY_LIMIT, REPLAY_WINDOW_MS, HEARTBEAT_GRACE_MS, REAUTHENTICATE_EVENT, FeedConnection, browserSignals, defaultOrderKey, type Clock, type FeedConnectionOptions, type FeedConnectionPhase, type FeedConnectionState, type FeedFrame, type FeedLoss, type FeedSignal, type FeedSignals, } from "./feed/connection.ts";
|
|
4
5
|
export { FeedOpenError, SSEParser, fetchOpener, isRefusal, type FeedOpener, type SSEEvent } from "./feed/sse.ts";
|
|
5
6
|
export type * from "./generated/feed.ts";
|
|
6
7
|
export type * from "./generated/kit.ts";
|
|
8
|
+
export type * from "./generated/shares.ts";
|
|
7
9
|
export type * from "./generated/workorder.ts";
|
|
8
10
|
export type * from "./generated/workorder-events.ts";
|
|
9
11
|
export { FEED_SCHEMAS } from "./generated/feed.ts";
|
|
10
12
|
export { KIT_ROUTE_PREFIX, KIT_ROUTE_TABLE, KIT_SCHEMAS, KIT_SIGNOUT_PATH } from "./generated/kit.ts";
|
|
13
|
+
export { SHARES_SCHEMAS } from "./generated/shares.ts";
|
|
11
14
|
export { WORK_ORDER_SCHEMAS } from "./generated/workorder.ts";
|
|
12
15
|
export { WORK_ORDER_EVENT_SCHEMAS } from "./generated/workorder-events.ts";
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Framework-free, with no runtime dependencies: it carries no UI component,
|
|
4
4
|
// because the framework is the author's.
|
|
5
|
-
export { ROUTE_PREFIX, routePath } from "./routes.js";
|
|
5
|
+
export { ROOT_BASE, ROUTE_PREFIX, appBase, routePath, underBase } from "./routes.js";
|
|
6
6
|
export { TeraClient, KitRequestError, UNRECOGNIZED_RESPONSE, } from "./client.js";
|
|
7
|
+
export { STEP_UP_HEADER, STEP_UP_POLL_MS, STEP_UP_REQUIRED, STEP_UP_RESUME_PARAM, StepUpError, resumedStepUp, stepUpChallengeOf, stepUpPageURL, } from "./stepup.js";
|
|
7
8
|
export { BASE_DELAY_MS, MAX_DELAY_MS, REPLAY_LIMIT, REPLAY_WINDOW_MS, HEARTBEAT_GRACE_MS, REAUTHENTICATE_EVENT, FeedConnection, browserSignals, defaultOrderKey, } from "./feed/connection.js";
|
|
8
9
|
export { FeedOpenError, SSEParser, fetchOpener, isRefusal } from "./feed/sse.js";
|
|
9
10
|
export { FEED_SCHEMAS } from "./generated/feed.js";
|
|
10
11
|
export { KIT_ROUTE_PREFIX, KIT_ROUTE_TABLE, KIT_SCHEMAS, KIT_SIGNOUT_PATH } from "./generated/kit.js";
|
|
12
|
+
export { SHARES_SCHEMAS } from "./generated/shares.js";
|
|
11
13
|
export { WORK_ORDER_SCHEMAS } from "./generated/workorder.js";
|
|
12
14
|
export { WORK_ORDER_EVENT_SCHEMAS } from "./generated/workorder-events.js";
|
package/dist/routes.d.ts
CHANGED
|
@@ -8,3 +8,18 @@ export declare const ROUTE_PREFIX = "/tera/v1/";
|
|
|
8
8
|
* collapses the dot segments and encoding does not change them.
|
|
9
9
|
*/
|
|
10
10
|
export declare function routePath(...segments: string[]): string;
|
|
11
|
+
/** The base of an app served at the root of its origin. */
|
|
12
|
+
export declare const ROOT_BASE = "/";
|
|
13
|
+
/**
|
|
14
|
+
* appBase checks the path an app is served under on its origin and answers it
|
|
15
|
+
* ending in `/`: `/` on a plugin's own origin, `/plugins/<name>/` on a
|
|
16
|
+
* path-based installation. A base that is not a root-absolute path on the
|
|
17
|
+
* page's own origin is refused.
|
|
18
|
+
*/
|
|
19
|
+
export declare function appBase(base?: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* underBase places a path the kit names under an app's base: a kit path
|
|
22
|
+
* (`/tera/v1/me`, from {@link routePath}) or a path relative to the base
|
|
23
|
+
* (`_tera/signout`, the kit's `signout_path`) alike.
|
|
24
|
+
*/
|
|
25
|
+
export declare function underBase(base: string, path: string): string;
|
package/dist/routes.js
CHANGED
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
// The route table itself is declared once, in Go, under sdk/plugin/webui, and
|
|
6
6
|
// generated into ./generated/kit.ts. What is here is how a path is built from
|
|
7
7
|
// it.
|
|
8
|
+
//
|
|
9
|
+
// The table's paths are the kit's own: tera's proxy serves a plugin either at
|
|
10
|
+
// the root of its own origin or, on a path-based installation, under
|
|
11
|
+
// `/plugins/<name>/` on tera's origin, and strips that prefix before the kit
|
|
12
|
+
// sees a request. A page therefore reaches every route, and tera's sign-out,
|
|
13
|
+
// under its app's base (`/` or `/plugins/<name>/`), which only the page knows.
|
|
8
14
|
import { KIT_ROUTE_PREFIX } from "./generated/kit.js";
|
|
9
15
|
/** The prefix every kit route is served under. */
|
|
10
16
|
export const ROUTE_PREFIX = KIT_ROUTE_PREFIX;
|
|
@@ -30,3 +36,25 @@ export function routePath(...segments) {
|
|
|
30
36
|
});
|
|
31
37
|
return ROUTE_PREFIX + parts.join("/");
|
|
32
38
|
}
|
|
39
|
+
/** The base of an app served at the root of its origin. */
|
|
40
|
+
export const ROOT_BASE = "/";
|
|
41
|
+
/**
|
|
42
|
+
* appBase checks the path an app is served under on its origin and answers it
|
|
43
|
+
* ending in `/`: `/` on a plugin's own origin, `/plugins/<name>/` on a
|
|
44
|
+
* path-based installation. A base that is not a root-absolute path on the
|
|
45
|
+
* page's own origin is refused.
|
|
46
|
+
*/
|
|
47
|
+
export function appBase(base = ROOT_BASE) {
|
|
48
|
+
if (!base.startsWith("/") || base.startsWith("//") || /[?#\\]/.test(base)) {
|
|
49
|
+
throw new TypeError(`appBase: ${JSON.stringify(base)} is not a root-absolute path on this origin`);
|
|
50
|
+
}
|
|
51
|
+
return base.endsWith("/") ? base : base + "/";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* underBase places a path the kit names under an app's base: a kit path
|
|
55
|
+
* (`/tera/v1/me`, from {@link routePath}) or a path relative to the base
|
|
56
|
+
* (`_tera/signout`, the kit's `signout_path`) alike.
|
|
57
|
+
*/
|
|
58
|
+
export function underBase(base, path) {
|
|
59
|
+
return appBase(base) + (path.startsWith("/") ? path.slice(1) : path);
|
|
60
|
+
}
|
package/dist/stepup.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A person's step-up, from the page's side (ADR-173 D11 step 3).
|
|
3
|
+
*
|
|
4
|
+
* An act the plugin requires the person's confirmation for is refused
|
|
5
|
+
* `step_up_required`: by the plugin's own route, in the kit's envelope with
|
|
6
|
+
* `error.step_up`, or by a Work Order verb, relayed by the invoke route with
|
|
7
|
+
* the challenge in the refusal's `data.step_up`. Either names the step-up's
|
|
8
|
+
* id and the page on tera's origin the person confirms it on. The client then:
|
|
9
|
+
*
|
|
10
|
+
* 1. opens that page in a new window, and when the browser will not open one,
|
|
11
|
+
* navigates to it instead with a `return_to` naming this page, which tera
|
|
12
|
+
* accepts only on the plugin's own origin;
|
|
13
|
+
* 2. polls `GET /tera/v1/step-ups/{id}` until the step-up is satisfied,
|
|
14
|
+
* declined or expired, and closes the window it opened;
|
|
15
|
+
* 3. sends the identical request again with `Tera-Step-Up: <id>` — or, for a
|
|
16
|
+
* Work Order verb, with `step_up` in its params.
|
|
17
|
+
*
|
|
18
|
+
* A step-up confirms one act once: nothing here holds an id past the retry it
|
|
19
|
+
* was confirmed for, except across the navigation fallback, where the id rides
|
|
20
|
+
* back on the `return_to` as {@link STEP_UP_RESUME_PARAM} and is spent by the
|
|
21
|
+
* first request that needs a step-up after the page loads again.
|
|
22
|
+
*/
|
|
23
|
+
import type { KitError } from "./generated/kit.ts";
|
|
24
|
+
/** The request header that carries a confirmed step-up's id to the plugin's route. */
|
|
25
|
+
export declare const STEP_UP_HEADER = "Tera-Step-Up";
|
|
26
|
+
/** The code of a refusal that needs the person's confirmation. */
|
|
27
|
+
export declare const STEP_UP_REQUIRED = "step_up_required";
|
|
28
|
+
/**
|
|
29
|
+
* The query parameter the navigation fallback adds to its `return_to`, naming
|
|
30
|
+
* the step-up the person went to confirm, so the page that loads again
|
|
31
|
+
* resumes it rather than beginning another.
|
|
32
|
+
*/
|
|
33
|
+
export declare const STEP_UP_RESUME_PARAM = "tera_step_up";
|
|
34
|
+
/** How often the step-up's state is read while the person confirms it, by default. */
|
|
35
|
+
export declare const STEP_UP_POLL_MS = 1000;
|
|
36
|
+
/** What a refusal names of the step-up it needs: the kit envelope's `error.step_up`. */
|
|
37
|
+
export type StepUpChallenge = NonNullable<KitError["error"]["step_up"]>;
|
|
38
|
+
/** The part of a `Window` the client uses: whether the person closed it, and closing it. */
|
|
39
|
+
export interface StepUpWindow {
|
|
40
|
+
readonly closed: boolean;
|
|
41
|
+
close(): void;
|
|
42
|
+
}
|
|
43
|
+
export interface StepUpOptions {
|
|
44
|
+
/** Opens the step-up's page in a new window; `window.open(url, "_blank")` when absent. Answers null when the browser would not open one. */
|
|
45
|
+
openWindow?: (url: string) => StepUpWindow | null;
|
|
46
|
+
/** The page's own URL, which the navigation fallback returns to; `location.href` when absent. */
|
|
47
|
+
pageURL?: () => string;
|
|
48
|
+
/** Waits between reads of the step-up's state; a timer when absent. */
|
|
49
|
+
sleep?: (ms: number) => Promise<void>;
|
|
50
|
+
/** How long to wait between reads; {@link STEP_UP_POLL_MS} when absent. */
|
|
51
|
+
pollIntervalMs?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* How a step-up ended without being confirmed:
|
|
55
|
+
* - `declined` — the person said they did not ask for it;
|
|
56
|
+
* - `expired` — nobody confirmed it in time;
|
|
57
|
+
* - `spent` — it confirmed another request already;
|
|
58
|
+
* - `abandoned` — the person closed its window and it is still waiting;
|
|
59
|
+
* - `navigated` — the browser would not open a window, so the page was sent to
|
|
60
|
+
* tera's; it returns here, and the next request that needs a step-up resumes
|
|
61
|
+
* this one.
|
|
62
|
+
*/
|
|
63
|
+
export type StepUpEnd = "declined" | "expired" | "spent" | "abandoned" | "navigated";
|
|
64
|
+
/** A step-up the person did not confirm: the request it was for was not sent again. */
|
|
65
|
+
export declare class StepUpError extends Error {
|
|
66
|
+
/** The step-up's id. */
|
|
67
|
+
readonly stepUpId: string;
|
|
68
|
+
/** How it ended. */
|
|
69
|
+
readonly end: StepUpEnd;
|
|
70
|
+
constructor(stepUpId: string, end: StepUpEnd, message: string);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The step-up a refusal needs confirmed, when it is one this client can have
|
|
74
|
+
* confirmed: code `step_up_required` with a page to open. A refusal naming an
|
|
75
|
+
* ended step-up carries no page, and is not one.
|
|
76
|
+
*/
|
|
77
|
+
export declare function stepUpChallengeOf(code: string, stepUp: unknown): StepUpChallenge | null;
|
|
78
|
+
/**
|
|
79
|
+
* The step-up page's URL with `return_to` set to `returnTo`, itself carrying
|
|
80
|
+
* {@link STEP_UP_RESUME_PARAM}. tera follows it back only when it is on the
|
|
81
|
+
* plugin's own origin.
|
|
82
|
+
*/
|
|
83
|
+
export declare function stepUpPageURL(pageURL: string, stepUpId: string, returnTo: string): string;
|
|
84
|
+
/** The step-up id a page loaded through the navigation fallback carries back, or null. */
|
|
85
|
+
export declare function resumedStepUp(pageURL: string): string | null;
|
|
86
|
+
export declare function defaultOpenWindow(url: string): StepUpWindow | null;
|
|
87
|
+
export declare function defaultSleep(ms: number): Promise<void>;
|