@looply/sdk 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +101 -3
- package/dist/client.d.ts +452 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +520 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +107 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +119 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/views.d.ts +723 -0
- package/dist/views.d.ts.map +1 -0
- package/dist/views.js +30 -0
- package/dist/views.js.map +1 -0
- package/package.json +33 -6
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vuedale
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,101 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @looply/sdk
|
|
2
|
+
|
|
3
|
+
A typed client for the looply HTTP API.
|
|
4
|
+
|
|
5
|
+
looply runs long autonomous coding sessions on your own machine. The daemon does
|
|
6
|
+
the work; the server holds the record of it — goals, the queue, what a run did,
|
|
7
|
+
and the decisions a person still has to make. This package is how a program
|
|
8
|
+
outside looply reads that record and takes part in those decisions.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @looply/sdk
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Using it
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
import { LooplyClient } from '@looply/sdk';
|
|
18
|
+
|
|
19
|
+
const looply = new LooplyClient({
|
|
20
|
+
baseUrl: 'https://api.looply.dev',
|
|
21
|
+
getToken: () => process.env.LOOPLY_TOKEN ?? null,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const [project] = await looply.projects();
|
|
25
|
+
const goals = await looply.goals(project.id, 'active');
|
|
26
|
+
|
|
27
|
+
for (const goal of goals) {
|
|
28
|
+
const report = await looply.autonomy(project.id, goal.id);
|
|
29
|
+
console.log(goal.text, report.autonomy.length, 'grant(s)');
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`getToken` is called for **every** request rather than read once, so a rotated
|
|
34
|
+
credential is picked up without rebuilding the client. `onUnauthorized` is called
|
|
35
|
+
on a 401, so a shell can drop to sign-in instead of retrying a dead token.
|
|
36
|
+
|
|
37
|
+
`fetch` is injectable and the package has no runtime dependencies — tests need no
|
|
38
|
+
network, and no version of `node-fetch` is imposed on you.
|
|
39
|
+
|
|
40
|
+
## What it can do
|
|
41
|
+
|
|
42
|
+
| | |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `projects()` | the projects this credential can see |
|
|
45
|
+
| `goals()` · `goal()` · `createGoal()` · `patchGoal()` | what you want done |
|
|
46
|
+
| `startGoal()` · `commandStatus()` | ask for work, and follow the request |
|
|
47
|
+
| `items()` · `status()` | the queue, and what a run is doing |
|
|
48
|
+
| `approvals()` · `approval()` · `decideApproval()` | consequential acts awaiting a person |
|
|
49
|
+
| `execution()` · `resolveExecution()` | governed executions awaiting a person |
|
|
50
|
+
| `autonomy()` | what a goal is authorised to pursue, and under whose grant |
|
|
51
|
+
| `events()` | the ledger, as it happened |
|
|
52
|
+
|
|
53
|
+
## Two things worth knowing before you build on this
|
|
54
|
+
|
|
55
|
+
**Approvals and executions refuse a machine token, by design.** An agent
|
|
56
|
+
authorising its own consequential act, or settling its own ambiguity, is the
|
|
57
|
+
thing they exist to prevent. `decideApproval` and `resolveExecution` require a
|
|
58
|
+
credential belonging to a person. A machine credential gets a 403, and that is
|
|
59
|
+
the feature.
|
|
60
|
+
|
|
61
|
+
**Nothing from `@looply/core` is re-exported here.** Core is the internal shared
|
|
62
|
+
vocabulary of the server, the CLI and the app, and it changes when they need it
|
|
63
|
+
to. Every type this package promises is declared in its own `views.ts`, so
|
|
64
|
+
depending on the SDK does not pin you to a release cycle you cannot see.
|
|
65
|
+
|
|
66
|
+
## Errors
|
|
67
|
+
|
|
68
|
+
Every failure is a `LooplyError` carrying a `code`, so you can branch on the
|
|
69
|
+
reason rather than parsing a message:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { LooplyError, isRetryable } from '@looply/sdk';
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
await looply.decideApproval(projectId, approvalId, {
|
|
76
|
+
decision: 'approve',
|
|
77
|
+
// Required. Retry safety comes from this OCC token rather than from an
|
|
78
|
+
// idempotency key: if the first call landed, the version has moved and the
|
|
79
|
+
// retry is a 409 that tells you so instead of deciding twice.
|
|
80
|
+
expectedVersion: approval.version,
|
|
81
|
+
});
|
|
82
|
+
} catch (e) {
|
|
83
|
+
if (e instanceof LooplyError && isRetryable(e.code)) {
|
|
84
|
+
// timeout or unavailable — trying again is reasonable
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`isRetryable` takes the **code**, not the error, and is the honest answer to "is
|
|
90
|
+
trying again worth anything?" — a 403 is not retryable however many times you
|
|
91
|
+
ask.
|
|
92
|
+
|
|
93
|
+
## Stability
|
|
94
|
+
|
|
95
|
+
**0.x.** The surface may change in a minor version. Every export in `index.ts` is
|
|
96
|
+
a deliberate promise — there is no `export *` — but the promise is a 0.x one
|
|
97
|
+
until an external consumer exists to hold it to.
|
|
98
|
+
|
|
99
|
+
## Licence
|
|
100
|
+
|
|
101
|
+
MIT. See [LICENSE](./LICENSE).
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import type { ApprovalView, CommandStatusView, GoalView, GovernedExecutionView, ItemView, KeeperAnswerView, PageView, PlatformEventView, ProjectView, RunStatusView, GoalAutonomyReport, GoalEvidenceView, PresenceView, SourceClassificationView, SourceDetailView, EvidenceAnchorView, RequirementLinkView, SourceAttestationView, SessionControlGrantView, SourceCoverageView, SourceDispositionView, SourceKindView, SourceView } from './views';
|
|
2
|
+
/**
|
|
3
|
+
* LOOPLY, AS A PROGRAM OUTSIDE IT SEES IT.
|
|
4
|
+
*
|
|
5
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
* 🔴 THIS IS THE HUMAN/BUSINESS SURFACE. IT IS NOT THE MACHINE ONE.
|
|
7
|
+
*
|
|
8
|
+
* A daemon claims approvals, begins executions and settles them. Those are
|
|
9
|
+
* MACHINE authority and they are deliberately absent here — not hidden behind a
|
|
10
|
+
* flag, not available with a different token, absent. Phase 7's whole property
|
|
11
|
+
* is that one approval yields at most one claim yields at most one execution,
|
|
12
|
+
* and the cheapest way to lose it is a convenient client method that lets a
|
|
13
|
+
* caller do the machine's half.
|
|
14
|
+
*
|
|
15
|
+
* So there is no `claim()`, no `beginExecution()`, no `settle()`, and no
|
|
16
|
+
* `popCommand()`. A client that needs them is a daemon, and a daemon has
|
|
17
|
+
* `packages/cli`.
|
|
18
|
+
*
|
|
19
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
* 🔴 EVERY MUTATION TAKES AN IDEMPOTENCY KEY, AND THAT IS NOT POLITENESS
|
|
21
|
+
*
|
|
22
|
+
* An external caller loses responses. It times out, it retries, its process
|
|
23
|
+
* restarts mid-request. Without a key, "create a goal" becomes two goals and —
|
|
24
|
+
* far worse — "start" becomes two Runs, spending two units of a person's
|
|
25
|
+
* autonomy budget for one instruction. The server already keys goal creation on
|
|
26
|
+
* `clientRef`; this makes the pattern uniform so no caller has to notice which
|
|
27
|
+
* routes are safe.
|
|
28
|
+
*
|
|
29
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
* WHAT IS DELIBERATELY NOT HERE
|
|
31
|
+
*
|
|
32
|
+
* ⚠️ MEMORY, INDEX AND GRAPH ARE MACHINE-LOCAL AND ARE NOT EXPOSED. Phase 11's
|
|
33
|
+
* memory, Phase 12's index and Phase 13's graph live in `.looply/state` on the
|
|
34
|
+
* developer's own machine, and they describe their private source code — an
|
|
35
|
+
* index names every file and symbol in the repository. Serving them from this
|
|
36
|
+
* API would mean shipping that to a server that does not have it today, which
|
|
37
|
+
* is a privacy regression dressed as a feature. See `docs/PLATFORM.md`.
|
|
38
|
+
*/
|
|
39
|
+
export interface LooplyClientOptions {
|
|
40
|
+
readonly baseUrl: string;
|
|
41
|
+
/**
|
|
42
|
+
* Called for every request, so a rotated credential is picked up without
|
|
43
|
+
* rebuilding the client.
|
|
44
|
+
*/
|
|
45
|
+
readonly getToken: () => string | null;
|
|
46
|
+
/** Called on a 401 so a shell can drop to sign-in rather than retrying. */
|
|
47
|
+
readonly onUnauthorized?: () => void;
|
|
48
|
+
readonly timeoutMs?: number;
|
|
49
|
+
/** Injected so this package has no runtime dependency and tests need no network. */
|
|
50
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
51
|
+
}
|
|
52
|
+
export declare class LooplyClient {
|
|
53
|
+
private readonly opts;
|
|
54
|
+
private readonly http;
|
|
55
|
+
constructor(opts: LooplyClientOptions);
|
|
56
|
+
/**
|
|
57
|
+
* ⚠️ THIS ROUTE ANSWERS A BARE ARRAY, NOT `{ projects }`.
|
|
58
|
+
*
|
|
59
|
+
* 🔴 THE FIRST DRAFT UNWRAPPED AN ENVELOPE THAT DOES NOT EXIST, and returned
|
|
60
|
+
* `undefined` typed as `ProjectView[]` — the cast asserted the envelope into
|
|
61
|
+
* being and TypeScript had nothing to object to. It was caught by
|
|
62
|
+
* `sdk-flagship.e2e.spec.ts`, which drives this client against a REAL server;
|
|
63
|
+
* a suite that mocked `fetch` would have returned whatever shape this method
|
|
64
|
+
* asked for and agreed with itself all the way to production.
|
|
65
|
+
*/
|
|
66
|
+
projects(): Promise<readonly ProjectView[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Create a goal, at most once per key.
|
|
69
|
+
*
|
|
70
|
+
* 🔴 `clientRef` IS THE IDEMPOTENCY KEY AND IT IS REQUIRED. There is no
|
|
71
|
+
* DELETE for a goal, so a duplicate from a retried POST is permanent. Sending
|
|
72
|
+
* the same key with the SAME text returns the same goal; sending it with
|
|
73
|
+
* DIFFERENT text is a conflict, because the key was a promise about which
|
|
74
|
+
* request this is.
|
|
75
|
+
*/
|
|
76
|
+
createGoal(projectId: string, input: {
|
|
77
|
+
readonly clientRef: string;
|
|
78
|
+
readonly text: string;
|
|
79
|
+
/** "B after A": ids of goals of the same project. Refused if unknown, itself, or a cycle (named). */
|
|
80
|
+
readonly dependsOn?: readonly string[];
|
|
81
|
+
/** Repository regions this goal may write to; canonicalised by the server. */
|
|
82
|
+
readonly surfaces?: readonly string[];
|
|
83
|
+
/** Which requirements and constraints of the project's sources this goal serves. */
|
|
84
|
+
readonly requirements?: readonly RequirementLinkView[];
|
|
85
|
+
}): Promise<GoalView>;
|
|
86
|
+
goal(projectId: string, goalId: string): Promise<GoalView>;
|
|
87
|
+
goals(projectId: string, state?: GoalView['state']): Promise<readonly GoalView[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Hand a document over, at most once per key AND at most once per content.
|
|
90
|
+
*
|
|
91
|
+
* A source is stored verbatim and content-addressed: the same bytes under a
|
|
92
|
+
* fresh `clientRef` answer with the source that already exists, and the same
|
|
93
|
+
* `clientRef` with different bytes is a conflict. What comes back is the
|
|
94
|
+
* stored record with its anchored statements — the extractor's answer, so a
|
|
95
|
+
* caller can see what Looply read before anything is built on it.
|
|
96
|
+
*
|
|
97
|
+
* ⚠️ `kind` is `markdown`, `text` or `pdf`. The text kinds send `content`;
|
|
98
|
+
* a `pdf` sends the `pages` of its text layer (as read on the machine that
|
|
99
|
+
* holds the file) and may carry the file's own sha256 as `originSha256`.
|
|
100
|
+
*/
|
|
101
|
+
createSource(projectId: string, input: {
|
|
102
|
+
readonly clientRef: string;
|
|
103
|
+
readonly name: string;
|
|
104
|
+
readonly kind: SourceKindView;
|
|
105
|
+
readonly content?: string;
|
|
106
|
+
readonly pages?: readonly {
|
|
107
|
+
readonly page: number;
|
|
108
|
+
readonly text: string;
|
|
109
|
+
}[];
|
|
110
|
+
readonly originSha256?: string;
|
|
111
|
+
}): Promise<SourceDetailView>;
|
|
112
|
+
/**
|
|
113
|
+
* Classify a source with the current classifier version, once.
|
|
114
|
+
*
|
|
115
|
+
* Idempotent per version: the rows that exist are answered as they are.
|
|
116
|
+
* What comes back says what each statement IS; nothing here says what the
|
|
117
|
+
* repository has done about it.
|
|
118
|
+
*/
|
|
119
|
+
classifySource(projectId: string, sourceId: string): Promise<{
|
|
120
|
+
classifications: readonly SourceClassificationView[];
|
|
121
|
+
classifierVersion: number;
|
|
122
|
+
created: boolean;
|
|
123
|
+
}>;
|
|
124
|
+
/**
|
|
125
|
+
* Record where each requirement of a source stands against the repository,
|
|
126
|
+
* as measured at one committed tree — once per (tree, reconciler version).
|
|
127
|
+
*
|
|
128
|
+
* The measurement is made where the project index lives (the machine that
|
|
129
|
+
* holds the repository; `looply source reconcile` is the usual caller) with
|
|
130
|
+
* `@looply/core`'s `reconcileStatements`; the server stores it verbatim and
|
|
131
|
+
* recomputes nothing. A second hand-over of the same tree answers the rows
|
|
132
|
+
* on record (`created: false`).
|
|
133
|
+
*
|
|
134
|
+
* 🔴 `implemented-and-evidenced` and `partial` are REFUSED here (400): a
|
|
135
|
+
* rule cannot put them on record. They are a person's attestation with
|
|
136
|
+
* evidence, which is a different act.
|
|
137
|
+
*/
|
|
138
|
+
reconcileSource(projectId: string, sourceId: string, input: {
|
|
139
|
+
readonly treeSha: string;
|
|
140
|
+
readonly reconcilerVersion: number;
|
|
141
|
+
readonly dispositions: readonly SourceDispositionView[];
|
|
142
|
+
}): Promise<{
|
|
143
|
+
dispositions: readonly SourceDispositionView[];
|
|
144
|
+
treeSha: string;
|
|
145
|
+
reconcilerVersion: number;
|
|
146
|
+
created: boolean;
|
|
147
|
+
}>;
|
|
148
|
+
/**
|
|
149
|
+
* Say, as a person, that a requirement is implemented-and-evidenced or
|
|
150
|
+
* partial — with at least one evidence anchor, at the committed tree the
|
|
151
|
+
* evidence was read at.
|
|
152
|
+
*
|
|
153
|
+
* 🔴 THIS NEEDS A DEVICE TOKEN. A machine token is refused (403): the machine
|
|
154
|
+
* measures (`reconcileSource`), a person vouches. A measurement's values are
|
|
155
|
+
* refused here (400). The same person saying the same thing at the same tree
|
|
156
|
+
* is one act: a repeat answers the record with `created: false`.
|
|
157
|
+
*/
|
|
158
|
+
attestSource(projectId: string, sourceId: string, input: {
|
|
159
|
+
readonly ordinal: number;
|
|
160
|
+
readonly disposition: 'implemented-and-evidenced' | 'partial';
|
|
161
|
+
readonly treeSha: string;
|
|
162
|
+
readonly anchors: readonly EvidenceAnchorView[];
|
|
163
|
+
readonly note?: string;
|
|
164
|
+
}): Promise<{
|
|
165
|
+
attestation: SourceAttestationView;
|
|
166
|
+
created: boolean;
|
|
167
|
+
}>;
|
|
168
|
+
/**
|
|
169
|
+
* What is covered and by whom: every requirement and constraint of a source
|
|
170
|
+
* with the goals that serve it, where it stands, what a person attested, and
|
|
171
|
+
* one word each. A read; nothing here is written by anyone.
|
|
172
|
+
*/
|
|
173
|
+
coverage(projectId: string, sourceId: string): Promise<SourceCoverageView>;
|
|
174
|
+
/**
|
|
175
|
+
* Every session-control grant this project has issued, live and historical.
|
|
176
|
+
*
|
|
177
|
+
* 🔴 THE MACHINE READS THESE AND WRITES NONE OF THEM. `OWNER_CHARTER.md` §5
|
|
178
|
+
* F-14 is explicit that only the server may issue one — a machine that could
|
|
179
|
+
* mint its own would be granting itself authority over a session, which is
|
|
180
|
+
* the whole thing the grant exists to prevent. So there is a reader here and
|
|
181
|
+
* deliberately no `issueSessionGrant`: issuing is a person's act, from a
|
|
182
|
+
* person's device, against the route that stamps their principal onto it.
|
|
183
|
+
*/
|
|
184
|
+
sessionGrants(projectId: string): Promise<readonly SessionControlGrantView[]>;
|
|
185
|
+
/**
|
|
186
|
+
* Record that a session acknowledged a grant, through the channel it came on.
|
|
187
|
+
*
|
|
188
|
+
* ⚠️ THE CHANNEL IS CLAIMED, NOT PROVED, AND THAT IS WHY IT IS RECORDED
|
|
189
|
+
* RATHER THAN TRUSTED. A session's adapter and a person's terminal can hold
|
|
190
|
+
* the same device token — the token says which DEVICE, never which program.
|
|
191
|
+
* So this writes down what arrived and `controlVerdict` in core refuses
|
|
192
|
+
* anything that is not `adapter`, which turns a person's attempt into a fact
|
|
193
|
+
* on the record instead of an inference nobody can check.
|
|
194
|
+
*/
|
|
195
|
+
acknowledgeSessionGrant(projectId: string, grantId: string, ack: {
|
|
196
|
+
readonly handshakeNonce: string;
|
|
197
|
+
readonly sessionId: string;
|
|
198
|
+
readonly workspace: string;
|
|
199
|
+
readonly repositoryId: string;
|
|
200
|
+
readonly scope: readonly string[];
|
|
201
|
+
readonly via: 'adapter' | 'operator';
|
|
202
|
+
}): Promise<SessionControlGrantView>;
|
|
203
|
+
/** A project's sources, newest first, without their content. */
|
|
204
|
+
sources(projectId: string): Promise<readonly SourceView[]>;
|
|
205
|
+
/** One source, verbatim, with its anchored statements, their latest classifications and the most recent reconciliation. */
|
|
206
|
+
source(projectId: string, sourceId: string): Promise<SourceDetailView>;
|
|
207
|
+
/**
|
|
208
|
+
* Ask Looply to work on a goal, once.
|
|
209
|
+
*
|
|
210
|
+
* 🔴 ONE EXPLICIT START ≤ ONE RUN, AND A LOST RESPONSE MUST NOT SPEND TWO.
|
|
211
|
+
* `clientRef` is what makes a retry safe: the same key names the same act of
|
|
212
|
+
* permission, so a repeat returns the command the first call created rather
|
|
213
|
+
* than authorising a second Start.
|
|
214
|
+
*
|
|
215
|
+
* ⚠️ IT IS REQUIRED HERE THOUGH THE SERVER TREATS IT AS OPTIONAL. The server
|
|
216
|
+
* has to accept keyless commands because the phone and the CLI have always
|
|
217
|
+
* sent none; an SDK written today has no such history and no reason to offer
|
|
218
|
+
* the unsafe shape. A caller who genuinely wants at-least-once can pass a
|
|
219
|
+
* fresh key each time — deliberately, rather than by omission.
|
|
220
|
+
*
|
|
221
|
+
* 🔴 THIS DEFECT WAS FOUND BY WRITING THIS METHOD. `POST /v1/commands` had no
|
|
222
|
+
* key at all, and the daemon derives a Start's request id from the COMMAND
|
|
223
|
+
* ID, so a retried enqueue was a second Start spending a second ordinal of a
|
|
224
|
+
* person's autonomy budget. Phase 15 added the key to the server.
|
|
225
|
+
*/
|
|
226
|
+
startGoal(projectId: string, goalId: string, input: {
|
|
227
|
+
readonly clientRef: string;
|
|
228
|
+
/**
|
|
229
|
+
* Wait for the machine up to this ISO instant (at most 7 days ahead)
|
|
230
|
+
* instead of the default hour. For an unattended caller: a laptop with
|
|
231
|
+
* its lid shut picks the Start up when it wakes, or it expires visibly.
|
|
232
|
+
*/
|
|
233
|
+
readonly deliverBy?: string;
|
|
234
|
+
}): Promise<{
|
|
235
|
+
readonly commandId: string;
|
|
236
|
+
}>;
|
|
237
|
+
/**
|
|
238
|
+
* Authorise BOUNDED AUTONOMOUS PURSUIT of a goal: the machine plans, runs and
|
|
239
|
+
* re-plans on its own, up to the server's budget (Starts and lifetime), until
|
|
240
|
+
* the goal is met, a person is needed, or the budget runs out.
|
|
241
|
+
*
|
|
242
|
+
* 🔴 THIS, NOT `startGoal`, IS WHAT AN UNATTENDED CALLER WANTS. `startGoal` is
|
|
243
|
+
* ONE run: when it ends nothing says whether the goal was met. A pursuit ends
|
|
244
|
+
* with a verdict — `satisfied`, `human_required`, `budget_exhausted` — read by
|
|
245
|
+
* `autonomy()` and `goalEvidence()`, and on `satisfied` the machine's own
|
|
246
|
+
* delivery comes with it.
|
|
247
|
+
*
|
|
248
|
+
* The SERVER stamps the version, the budget and the expiry; the client names
|
|
249
|
+
* the goal and nothing else, so a caller cannot pin a budget it was not given.
|
|
250
|
+
* Idempotent on `clientRef`, which matters doubly here: authorising SPENDS the
|
|
251
|
+
* grant, so a lost response retried without the key would spend it twice.
|
|
252
|
+
*/
|
|
253
|
+
authorizeGoalAutonomy(projectId: string, goalId: string, input: {
|
|
254
|
+
readonly clientRef: string;
|
|
255
|
+
readonly deliverBy?: string;
|
|
256
|
+
}): Promise<{
|
|
257
|
+
readonly commandId: string;
|
|
258
|
+
}>;
|
|
259
|
+
/**
|
|
260
|
+
* Is the machine that holds this project awake? A Start is delivered by the
|
|
261
|
+
* machine polling, so this is the first half of "will my Start run".
|
|
262
|
+
*/
|
|
263
|
+
presence(projectId: string): Promise<PresenceView>;
|
|
264
|
+
/**
|
|
265
|
+
* What became of a command.
|
|
266
|
+
*
|
|
267
|
+
* `startGoal` returns an id and then goes quiet; this is the durable answer —
|
|
268
|
+
* started, terminally refused, and why.
|
|
269
|
+
*
|
|
270
|
+
* ⚠️ COMMAND TRUTH ONLY. `done` on a start-run means the Start reached its
|
|
271
|
+
* success boundary, NOT that the run finished or the goal was met. A caller
|
|
272
|
+
* wanting the whole picture composes this with `status()` and `events()`.
|
|
273
|
+
*/
|
|
274
|
+
commandStatus(projectId: string, commandId: string): Promise<CommandStatusView>;
|
|
275
|
+
/** Amend or abandon a goal. `version` is the OCC token the read returned. */
|
|
276
|
+
patchGoal(projectId: string, goalId: string, input: {
|
|
277
|
+
readonly state?: GoalView['state'];
|
|
278
|
+
readonly text?: string;
|
|
279
|
+
/** Replaces the list. Bumps the version like a change of words. */
|
|
280
|
+
readonly dependsOn?: readonly string[];
|
|
281
|
+
readonly surfaces?: readonly string[];
|
|
282
|
+
/** Replaces the set of requirements this goal serves. */
|
|
283
|
+
readonly requirements?: readonly RequirementLinkView[];
|
|
284
|
+
readonly version: number;
|
|
285
|
+
}): Promise<GoalView>;
|
|
286
|
+
items(projectId: string): Promise<readonly ItemView[]>;
|
|
287
|
+
/**
|
|
288
|
+
* The current run, as a projection.
|
|
289
|
+
*
|
|
290
|
+
* ⚠️ THERE IS NO `/runs` COLLECTION, so this SDK does not pretend to one. The
|
|
291
|
+
* server keeps a single latest-run projection per project — which is what the
|
|
292
|
+
* product actually shows — and run HISTORY lives in the event ledger, reached
|
|
293
|
+
* through `events()`.
|
|
294
|
+
*/
|
|
295
|
+
status(projectId: string): Promise<RunStatusView>;
|
|
296
|
+
/**
|
|
297
|
+
* Ask the keeper about a project (DESIGN §9 read path).
|
|
298
|
+
*
|
|
299
|
+
* A POST that READS. The question travels in the body rather than a query
|
|
300
|
+
* string, because a sentence about somebody's codebase does not belong in an
|
|
301
|
+
* access log — and because the answer quotes item titles, commit shas and the
|
|
302
|
+
* implementer's own round notes, it needs the same grant `status()` does.
|
|
303
|
+
*
|
|
304
|
+
* ⚠️ NOTHING HERE ACTS. The keeper’s write path is deliberately not a second
|
|
305
|
+
* set of methods: an intent goes through the routes a person already uses —
|
|
306
|
+
* `command()`, `patchItem()`, answering a question — with `actor: keeper` on
|
|
307
|
+
* the record, so there is no privileged path for it to take.
|
|
308
|
+
*/
|
|
309
|
+
ask(projectId: string, question: string): Promise<KeeperAnswerView>;
|
|
310
|
+
/**
|
|
311
|
+
* ⚠️ THE APPROVAL ROUTES ANSWER BARE VALUES, NOT ENVELOPES.
|
|
312
|
+
*
|
|
313
|
+
* The goal and queue routes DO wrap (`{ goals }`, `{ items }`) and these do
|
|
314
|
+
* not. There is no rule to infer here — it is simply how each controller was
|
|
315
|
+
* written — which is exactly why this client is checked against a running
|
|
316
|
+
* server rather than against a design document.
|
|
317
|
+
*/
|
|
318
|
+
approvals(projectId: string): Promise<readonly ApprovalView[]>;
|
|
319
|
+
approval(projectId: string, approvalId: string): Promise<ApprovalView>;
|
|
320
|
+
/**
|
|
321
|
+
* Advise on a pending approval: approve or deny, and why.
|
|
322
|
+
*
|
|
323
|
+
* 🔴 THIS IS WHAT AN INTEGRATION CAN DO WITH AN APPROVAL, AND ALL IT CAN DO.
|
|
324
|
+
* Deciding is a person's authority (`decideApproval` needs an owner's device
|
|
325
|
+
* token); an integration that has reviewed the action in its own process says
|
|
326
|
+
* what it concluded here, and the owner is notified and decides with the
|
|
327
|
+
* advice in front of them. Pending only (a 409 otherwise); latest wins, so a
|
|
328
|
+
* retry is harmless.
|
|
329
|
+
*/
|
|
330
|
+
recommendApproval(projectId: string, approvalId: string, input: {
|
|
331
|
+
readonly decision: 'approve' | 'deny';
|
|
332
|
+
readonly note?: string;
|
|
333
|
+
}): Promise<ApprovalView>;
|
|
334
|
+
/**
|
|
335
|
+
* Approve or deny one exact action.
|
|
336
|
+
*
|
|
337
|
+
* 🔴 A PERSON DOES THIS. A machine credential is refused by the server, and
|
|
338
|
+
* that refusal is the security content of the route rather than an
|
|
339
|
+
* inconvenience — the hazard is not the 403, it is somebody meeting it and
|
|
340
|
+
* widening the guard so a machine can authorise its own work.
|
|
341
|
+
*
|
|
342
|
+
* `version` is the approval's OCC token: deciding against a stale one is a
|
|
343
|
+
* conflict, not a silent overwrite, because the thing being approved may have
|
|
344
|
+
* expired or been revoked since it was read.
|
|
345
|
+
*/
|
|
346
|
+
decideApproval(projectId: string, approvalId: string, input: {
|
|
347
|
+
/**
|
|
348
|
+
* 🔴 `revoke` IS A REAL DECISION AND THE FIRST DRAFT OMITTED IT. Taking
|
|
349
|
+
* back an authorisation before it is acted on is exactly the operation a
|
|
350
|
+
* person most urgently needs, and a client that could not express it
|
|
351
|
+
* would send them to another device to do it.
|
|
352
|
+
*/
|
|
353
|
+
readonly decision: 'approve' | 'deny' | 'revoke';
|
|
354
|
+
/**
|
|
355
|
+
* 🔴 THE FIELD IS `expectedVersion`, AND SENDING `version` MEANT SENDING
|
|
356
|
+
* NOTHING. The server requires a whole number here and refuses without
|
|
357
|
+
* one, so this method would have 400'd on every call. There was no
|
|
358
|
+
* `requestKey` either — a name this SDK invented for a route that has
|
|
359
|
+
* never accepted it. Both were found by reading the controller.
|
|
360
|
+
*
|
|
361
|
+
* Retry safety comes from the OCC token rather than from a key: if the
|
|
362
|
+
* first call landed, the version has moved, and the retry is a 409 that
|
|
363
|
+
* tells the caller so instead of deciding twice.
|
|
364
|
+
*/
|
|
365
|
+
readonly expectedVersion: number;
|
|
366
|
+
/** Safe prose from a person, kept with the decision. */
|
|
367
|
+
readonly note?: string;
|
|
368
|
+
}): Promise<ApprovalView>;
|
|
369
|
+
execution(projectId: string, executionId: string): Promise<GovernedExecutionView>;
|
|
370
|
+
/**
|
|
371
|
+
* Tell Looply what actually happened, when it could not establish that itself.
|
|
372
|
+
*
|
|
373
|
+
* 🔴 THIS CLOSES A GAP PHASE 8 LEFT ON PURPOSE. The resolution route has been
|
|
374
|
+
* owner-guarded and mutation-covered since Phase 8 and had NO CLIENT — and its
|
|
375
|
+
* client could not be the CLI, because `server-client.ts` authenticates with a
|
|
376
|
+
* machine token and the route refuses a machine BY DESIGN. A machine settling
|
|
377
|
+
* its own ambiguity is the one thing the route exists to prevent. It belongs
|
|
378
|
+
* to a person, so it belongs here.
|
|
379
|
+
*
|
|
380
|
+
* ⚠️ `note` IS PRIVATE HUMAN TESTIMONY. It is why a person believes what they
|
|
381
|
+
* are asserting, it is kept out of every machine- and model-facing view, and a
|
|
382
|
+
* client must never render it into anything a model reads.
|
|
383
|
+
*/
|
|
384
|
+
resolveExecution(projectId: string, executionId: string, input: {
|
|
385
|
+
readonly outcome?: 'succeeded' | 'failed';
|
|
386
|
+
/**
|
|
387
|
+
* ⚠️ NO KEY AND NO VERSION — this route accepts neither, and inventing
|
|
388
|
+
* one here would be a field the server discards while the caller believes
|
|
389
|
+
* they are protected by it. What makes a repeat safe is that a resolution
|
|
390
|
+
* is recorded once and never rewrites `state`.
|
|
391
|
+
*/
|
|
392
|
+
readonly note?: string;
|
|
393
|
+
}): Promise<GovernedExecutionView>;
|
|
394
|
+
/**
|
|
395
|
+
* Whether autonomous pursuit of a goal is still running, and why it stopped.
|
|
396
|
+
*
|
|
397
|
+
* ⚠️ THIS IS THE AUTONOMY VIEW, NOT A SAFETY ENDPOINT. There is no
|
|
398
|
+
* `/safety` route: a loop-safety hold is enforced ON THE MACHINE, in
|
|
399
|
+
* `loop-safety-store.ts`, and never travels to the server. What the server
|
|
400
|
+
* knows is that pursuit ENDED and the reason it was given — which is what a
|
|
401
|
+
* person needs to see, and is version-scoped because a hold on version 4 must
|
|
402
|
+
* not block version 5.
|
|
403
|
+
*/
|
|
404
|
+
autonomy(projectId: string, goalId: string): Promise<GoalAutonomyReport>;
|
|
405
|
+
/**
|
|
406
|
+
* What the server saw of a goal being delivered, per version.
|
|
407
|
+
*
|
|
408
|
+
* This used to say there was no `/evidence` route and that one would be a
|
|
409
|
+
* server change, not an SDK one. It is now that server change:
|
|
410
|
+
* `GET …/goals/:goalId/evidence` stitches, once, the runs that pursued each
|
|
411
|
+
* version, every round's commit with the gate's and the prover's verdicts,
|
|
412
|
+
* where each pursuit came to rest, and what was pushed under an approval.
|
|
413
|
+
*
|
|
414
|
+
* ⚠️ NOT THE MACHINE'S PROOF. Whether a goal was met is decided on the
|
|
415
|
+
* machine; this is what reached the server. Render `pursuits[].state ===
|
|
416
|
+
* 'satisfied'` as the machine's claim and `landed` as the commits behind it —
|
|
417
|
+
* never as "proven". Whitelisted: no gate output, no prover prose, no remote.
|
|
418
|
+
*/
|
|
419
|
+
goalEvidence(projectId: string, goalId: string): Promise<GoalEvidenceView>;
|
|
420
|
+
/**
|
|
421
|
+
* One page of events, resuming from a cursor.
|
|
422
|
+
*
|
|
423
|
+
* 🔴 REST REPLAY IS THE CORRECTNESS PATH; A SOCKET IS ONLY AN ACCELERATOR. A
|
|
424
|
+
* client that has been away — asleep, offline, restarted — reconstructs by
|
|
425
|
+
* paging from the last cursor it stored. A live stream that missed an event
|
|
426
|
+
* has no way to notice, so it may never be the only way state arrives.
|
|
427
|
+
*
|
|
428
|
+
* ⚠️ DUPLICATES ARE SAFE AND EXPECTED. `id` is stable, so a client that has
|
|
429
|
+
* seen one can drop it; a client that has NOT seen one must not be missing it.
|
|
430
|
+
* Delivering twice is the cheap failure, and not delivering is the expensive
|
|
431
|
+
* one.
|
|
432
|
+
*/
|
|
433
|
+
events(projectId: string, opts?: {
|
|
434
|
+
readonly after?: string;
|
|
435
|
+
readonly limit?: number;
|
|
436
|
+
}): Promise<PageView<PlatformEventView>>;
|
|
437
|
+
/**
|
|
438
|
+
* 🔴 THE QUERY IS A SEPARATE ARGUMENT, NEVER INTERPOLATED INTO `path`.
|
|
439
|
+
*
|
|
440
|
+
* `path` is therefore always a literal route with parameter slots and nothing
|
|
441
|
+
* else, which is what lets `boundary.spec.ts` compare it to the server's route
|
|
442
|
+
* table exactly rather than by heuristic. An earlier version appended
|
|
443
|
+
* `${q}` inside the template and the guard could not tell a query suffix from
|
|
444
|
+
* a path segment — it read `/goals?state=x` as a route called `/goals:param`.
|
|
445
|
+
* Fixing the guard's parser instead would have left the ambiguity in place for
|
|
446
|
+
* the next method to trip over.
|
|
447
|
+
*
|
|
448
|
+
* `undefined` values are dropped rather than sent as the string "undefined".
|
|
449
|
+
*/
|
|
450
|
+
private request;
|
|
451
|
+
}
|
|
452
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|