halfcycle 0.4.7 → 0.4.9
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/.claude-plugin/plugin.json +1 -1
- package/bin/bin.bundle.mjs +2217 -280
- package/commands/agent-teams-orchestration.md +1 -1
- package/commands/consistency-check.md +1 -1
- package/commands/context-update.md +1 -1
- package/commands/halfcycle-design.md +1 -1
- package/commands/halfcycle-setup.md +1 -1
- package/commands/stack-assembly-worker.md +1 -1
- package/commands/task-execution.md +1 -1
- package/commands/task-graph.md +1 -1
- package/commands/write-spec.md +1 -1
- package/dist/bin.d.ts +2 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/build-record/obtain.d.ts +14 -7
- package/dist/build-record/obtain.d.ts.map +1 -1
- package/dist/build-record/render-v2.d.ts +32 -6
- package/dist/build-record/render-v2.d.ts.map +1 -1
- package/dist/build-record/write.d.ts +2 -2
- package/dist/build-record/write.d.ts.map +1 -1
- package/dist/cli-contract.d.ts +2 -9
- package/dist/cli-contract.d.ts.map +1 -1
- package/dist/cli.js +3194 -1402
- package/dist/cli.js.map +3 -3
- package/dist/close-phase.d.ts +215 -134
- package/dist/close-phase.d.ts.map +1 -1
- package/dist/draw/index.d.ts +25 -5
- package/dist/draw/index.d.ts.map +1 -1
- package/dist/identity.d.ts +78 -9
- package/dist/identity.d.ts.map +1 -1
- package/dist/index.js +1629 -209
- package/dist/index.js.map +3 -3
- package/dist/install.d.ts +16 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/loopback-signin.d.ts.map +1 -1
- package/dist/open-phase.d.ts +25 -1
- package/dist/open-phase.d.ts.map +1 -1
- package/dist/plan.d.ts +59 -18
- package/dist/plan.d.ts.map +1 -1
- package/dist/pre-create-checks.d.ts.map +1 -1
- package/dist/review.d.ts +228 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/shown-record.d.ts +46 -0
- package/dist/shown-record.d.ts.map +1 -0
- package/dist/system-report.d.ts +28 -4
- package/dist/system-report.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/project-page.d.ts +0 -24
- package/dist/project-page.d.ts.map +0 -1
package/dist/close-phase.d.ts
CHANGED
|
@@ -1,45 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Close-phase wiring — the CLI's
|
|
3
|
-
*
|
|
2
|
+
* Close-phase wiring — the CLI's half of the close review (feature
|
|
3
|
+
* `close-review-and-carry-drop` AC1, decision 2; System view · E3).
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* WHAT THIS VERB DOES NOW. It closes nothing. A phase closes only on its owner's last
|
|
6
|
+
* review decision, which the control service makes inside that decision's own
|
|
7
|
+
* transaction. This verb is the coordinator's act: it carries what the coordinator
|
|
8
|
+
* knows — the walk's verdict and findings (INV-009: sourced from the acceptance walk,
|
|
9
|
+
* never inferred), who ran the close step, and the client's statements — and asks the
|
|
10
|
+
* service to open the review. It writes no Build Record and clears no phase stamp:
|
|
11
|
+
* the phase is still open. `build-record <phase>`, run once the owner's last decision
|
|
12
|
+
* has closed it, writes the record and clears the stamp (`build-record/obtain.ts`).
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* THE ORDER, AND WHY.
|
|
15
|
+
* 1. The whole request is checked against the route's own schema
|
|
16
|
+
* (`openReviewRequestSchema`, the one home of its shape, INV-003) BEFORE anything
|
|
17
|
+
* is sent — a request this machine refuses sends nothing, not even the counts.
|
|
18
|
+
* 2. The commit HEAD points at is read (`readHeadCommit`), so the statements carry
|
|
19
|
+
* the commit the review starts from.
|
|
20
|
+
* 3. A fresh count of what changed under each part is sent through the runner's
|
|
21
|
+
* `observe` verb (`what-halfcycle-saw` AC3, the unthrottled sender), so the review
|
|
22
|
+
* starts from the commit the walk saw. The runner is SPAWNED as a child process,
|
|
23
|
+
* never imported: this package may import only the two shared packages
|
|
24
|
+
* (INV-001), and counting keeps one home, the runner's. The project credential
|
|
25
|
+
* this verb already read travels through the child's environment under the names
|
|
26
|
+
* the runner's own configuration reader reads. Whatever the child answers, the
|
|
27
|
+
* open goes ahead: a count that could not be sent is said once by the open
|
|
28
|
+
* answer's `counted`, never by a line of this verb's own.
|
|
29
|
+
* 4. The open request is posted, and the answer is parsed through
|
|
30
|
+
* `openReviewAnswerSchema`. Each outcome prints its own sentence (CL1–CL6, CL12,
|
|
31
|
+
* and the typed review's H1), written out below exactly as the spec words them.
|
|
17
32
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* that both topologies can read — see `PhaseEntryConditionError`.
|
|
33
|
+
* `override` IS GONE FROM THE CLOSE (W1-3). There is no way through an unfinished step:
|
|
34
|
+
* the remedy is to finish it, decline it or pass its review again. The method version
|
|
35
|
+
* does not move at the close either (W1-5); only `open-phase` moves it, so this verb
|
|
36
|
+
* never touches the committed pin.
|
|
23
37
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* derive-then-transition ordering is the orchestrator's. This module builds the
|
|
28
|
-
* request, sends it, and reports what came back.
|
|
38
|
+
* TOPOLOGY. This verb names no capability only Studio has: the open route takes the
|
|
39
|
+
* engagement credential alone, needs no GitHub installation, no portal session and no
|
|
40
|
+
* `delivering` status (INV-022).
|
|
29
41
|
*
|
|
30
|
-
* INV-001: this file imports the global `fetch
|
|
31
|
-
* `@halfcycle/
|
|
32
|
-
* import. `acceptPhaseRequestSchema` is the ONE home for the request's shape
|
|
33
|
-
* (INV-003), so the CLI validates the whole body it builds against the same schema
|
|
34
|
-
* the route parses with. It never imports the control service.
|
|
42
|
+
* INV-001: this file imports the global `fetch`, Node builtins, `@halfcycle/events`
|
|
43
|
+
* and `@halfcycle/core`. It never imports the control service or the runner.
|
|
35
44
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* note. The service freezes both into the phase's Build Record; the caller fetches
|
|
39
|
-
* that record afterwards (`build-record/obtain.ts`).
|
|
45
|
+
* SHIPS TO CLIENT DISK inside the CLI: every string here is a sentence a person reads,
|
|
46
|
+
* and no comment sits beside an object member.
|
|
40
47
|
*/
|
|
41
|
-
import { type AcceptanceOutcome, type
|
|
42
|
-
import
|
|
48
|
+
import { unfinishedStepLine, type AcceptanceOutcome, type ObserveRunResult, type OpenReviewAnswer } from '@halfcycle/events';
|
|
49
|
+
import type { RepoCredential } from './open-phase.js';
|
|
43
50
|
/**
|
|
44
51
|
* Whether the commit this phase closed at could be read, and if so the full hash
|
|
45
52
|
* that travelled with the close. When it could not, `reason` says why in words a
|
|
@@ -63,121 +70,195 @@ export interface StatedStatements {
|
|
|
63
70
|
}
|
|
64
71
|
/** Nothing stated — what a close sends when no statement flag was given. */
|
|
65
72
|
export declare const NO_STATEMENTS: StatedStatements;
|
|
66
|
-
/** What `POST /engagements/:id/accept` returns on 200 (the fields the CLI reports). */
|
|
67
|
-
export interface ClosedPhase {
|
|
68
|
-
engagementId: string;
|
|
69
|
-
/** The lifecycle status after the close — `closed`. */
|
|
70
|
-
status: string;
|
|
71
|
-
/**
|
|
72
|
-
* Set when the phase closed but this machine's record of it could not be
|
|
73
|
-
* cleared. `null` on every ordinary success. Until it is cleared, work on this
|
|
74
|
-
* machine is still filed under a phase that is no longer open.
|
|
75
|
-
*/
|
|
76
|
-
stampFailure: PhaseStampFailure | null;
|
|
77
|
-
/** The commit sent with the close, or why none could be read. */
|
|
78
|
-
closeCommit: CloseCommitOutcome;
|
|
79
|
-
/**
|
|
80
|
-
* The method version this close moved the project to (`existing-projects-carry-on`
|
|
81
|
-
* AC2), or `null` when it did not move. An older control's answer carries no
|
|
82
|
-
* field at all, which reads the same as `null` here — this CLI then prints
|
|
83
|
-
* and writes nothing about a move, exactly as it did before this field existed.
|
|
84
|
-
*/
|
|
85
|
-
methodUpdated: MethodUpdate | null;
|
|
86
|
-
}
|
|
87
73
|
/**
|
|
88
|
-
*
|
|
74
|
+
* Why the full HEAD commit of a named repository could not be read, in one place
|
|
75
|
+
* both `open-phase` and `close-phase` read (`what-halfcycle-saw` AC1):
|
|
76
|
+
* - `no-repository` — no folder was named for the read, or the named folder is not
|
|
77
|
+
* a git repository at all.
|
|
78
|
+
* - `no-commit` — the folder IS a repository, with no commit on it yet.
|
|
79
|
+
* - `unreadable` — git could not be run at all, or its answer was not a full
|
|
80
|
+
* commit hash. `missingGit` tells those two apart: `close-phase` has always
|
|
81
|
+
* printed them as two separate sentences (`readCloseCommit`, below), so the
|
|
82
|
+
* detail travels on the cause rather than being thrown away here.
|
|
83
|
+
*/
|
|
84
|
+
export type HeadCommitCause = 'no-repository' | 'no-commit' | 'unreadable';
|
|
85
|
+
/** Whether the full HEAD commit of a named repository could be read, and why not. */
|
|
86
|
+
export type HeadCommitOutcome = {
|
|
87
|
+
read: true;
|
|
88
|
+
commit: string;
|
|
89
|
+
} | {
|
|
90
|
+
read: false;
|
|
91
|
+
cause: 'no-repository' | 'no-commit';
|
|
92
|
+
} | {
|
|
93
|
+
read: false;
|
|
94
|
+
cause: 'unreadable';
|
|
95
|
+
missingGit: boolean;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Read the full HEAD commit of the NAMED repository.
|
|
99
|
+
*
|
|
100
|
+
* ONE READER FOR BOTH VERBS. `close-phase` reads HEAD to send where a phase ends
|
|
101
|
+
* (`readCloseCommit`, below, is this function's body under the name that verb has
|
|
102
|
+
* always used); `open-phase` reads it to send where a phase starts
|
|
103
|
+
* (`what-halfcycle-saw` AC1). One way to read a commit off the person's disk, not two
|
|
104
|
+
* that could disagree about what "unreadable" means.
|
|
89
105
|
*
|
|
90
106
|
* `gitEnvForNamedRepo` strips the variables that tell git which repository to use,
|
|
91
107
|
* so an absolute `GIT_DIR` inherited from a hook cannot substitute another
|
|
92
|
-
* repository's HEAD for this one's. git's own stderr is discarded: a
|
|
93
|
-
* is expected, the
|
|
94
|
-
* The hash is checked by the contract's own
|
|
95
|
-
* malformed answer is never
|
|
108
|
+
* repository's HEAD for this one's. git's own stderr is discarded throughout: a
|
|
109
|
+
* failure here is expected, the caller still proceeds, and it says why in this
|
|
110
|
+
* product's own words, never git's. The hash is checked by the contract's own
|
|
111
|
+
* `closeCommitSchema`, so a short or malformed answer is never treated as read.
|
|
112
|
+
*
|
|
113
|
+
* `no-repository` and `no-commit` are told apart by a second call
|
|
114
|
+
* (`rev-parse --git-dir`), made only when the first failed for a reason other than
|
|
115
|
+
* git being missing: if the folder IS a repository, that first failure can only mean
|
|
116
|
+
* it has no commit yet.
|
|
96
117
|
*/
|
|
97
|
-
export declare function
|
|
118
|
+
export declare function readHeadCommit(repoRoot: string | undefined): HeadCommitOutcome;
|
|
98
119
|
/**
|
|
99
|
-
*
|
|
120
|
+
* Read the full HEAD commit of the NAMED repository, before the close is sent.
|
|
100
121
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
*
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
finding?: string | undefined,
|
|
139
|
-
/**
|
|
140
|
-
* The plane's own name for the refusal (`error` on the body) — e.g.
|
|
141
|
-
* `PhaseAlreadyClosed`, `PhaseCloseConditionUnmet`, `PhaseNotOpen`.
|
|
142
|
-
*
|
|
143
|
-
* WHY IT IS CARRIED (walk 8 `F-1`). The CLI used to read a bare `409` as "this
|
|
144
|
-
* phase is already closed" and print that as advice. Once a wrong phase NAME
|
|
145
|
-
* became its own 409, that line printed underneath a refusal saying the opposite
|
|
146
|
-
* — the plane said *phase 1 is open, close that one* and the CLI said *it is
|
|
147
|
-
* already closed*. Guessing a cause from a status code is how a remedy string
|
|
148
|
-
* comes to contradict the refusal above it; the code is read, not inferred.
|
|
149
|
-
*/
|
|
150
|
-
code?: string | undefined);
|
|
151
|
-
}
|
|
122
|
+
* `readHeadCommit`'s body, mapped to the two sentences this verb has always
|
|
123
|
+
* printed for `unreadable` — git being missing on this machine, and git running
|
|
124
|
+
* but not answering with a full hash, read differently by whoever hits them, so
|
|
125
|
+
* they stay two sentences rather than merging into one that explains neither.
|
|
126
|
+
*/
|
|
127
|
+
export declare function readCloseCommit(repoRoot: string | undefined): CloseCommitOutcome;
|
|
128
|
+
/**
|
|
129
|
+
* The longest the `observe` child may run before it is stopped and the open goes ahead
|
|
130
|
+
* without it. The child makes two requests with a 1.5 s deadline each and a handful of
|
|
131
|
+
* git calls with their own caps; this is a backstop for a child that hangs, not a
|
|
132
|
+
* budget it is expected to use.
|
|
133
|
+
*/
|
|
134
|
+
export declare const OBSERVE_CHILD_DEADLINE_MS = 30000;
|
|
135
|
+
/**
|
|
136
|
+
* The environment names the runner's configuration reader takes the project
|
|
137
|
+
* credential from: the token, the project id, and the service address. Named once,
|
|
138
|
+
* here, because the runner cannot be imported to read them (INV-001); the spawn test
|
|
139
|
+
* proves the child reads exactly these.
|
|
140
|
+
*/
|
|
141
|
+
export declare const OBSERVE_CHILD_CREDENTIAL_ENV: {
|
|
142
|
+
readonly token: "GUARD_SERVICE_TOKEN";
|
|
143
|
+
readonly engagementId: "GUARD_ENGAGEMENT_ID";
|
|
144
|
+
readonly serviceUrl: "HALFCYCLE_SERVICE_URL";
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* The child's environment: this process's, without the variables that tell git which
|
|
148
|
+
* repository to use (an absolute `GIT_DIR` inherited from a hook would otherwise count
|
|
149
|
+
* another repository), and with the project credential this verb already read set
|
|
150
|
+
* under the runner's own names — so the child counts for the same project, against the
|
|
151
|
+
* same service, that the open is sent to.
|
|
152
|
+
*/
|
|
153
|
+
export declare function observeChildEnv(credential: RepoCredential): NodeJS.ProcessEnv;
|
|
154
|
+
/**
|
|
155
|
+
* The one line the `observe` child printed, read through `observeRunResultSchema`, or
|
|
156
|
+
* `unreachable` when stdout holds no such line.
|
|
157
|
+
*/
|
|
158
|
+
export declare function readObserveLine(stdout: string): ObserveRunResult;
|
|
152
159
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
160
|
+
* Send a fresh count by running the runner binary this package ships, as a child
|
|
161
|
+
* process, in the named repository: `node <binary> observe`. Never throws, never
|
|
162
|
+
* prints: a binary that cannot be found (`binary` is the error that said so), a child
|
|
163
|
+
* that cannot start, runs past `OBSERVE_CHILD_DEADLINE_MS` or prints no result line
|
|
164
|
+
* all read `unreachable`, and the open goes ahead.
|
|
165
|
+
*/
|
|
166
|
+
export declare function runObserveChild(binary: string | Error, credential: RepoCredential, repoRoot: string): Promise<ObserveRunResult>;
|
|
167
|
+
/**
|
|
168
|
+
* A close step refused on this machine, before anything was sent: the request failed
|
|
169
|
+
* the shared request schema. The CLI prints the message and exits as a usage error.
|
|
155
170
|
*/
|
|
156
171
|
export declare class CloseRequestInvalid extends Error {
|
|
157
172
|
constructor(message: string);
|
|
158
173
|
}
|
|
159
174
|
/**
|
|
160
|
-
*
|
|
175
|
+
* What came back from the open route:
|
|
176
|
+
* - `answered`: a body the open route's own answer schema accepts — one of its
|
|
177
|
+
* outcomes, or the not-open body;
|
|
178
|
+
* - `refused`: any other answer that was not a success, with its status and the
|
|
179
|
+
* service's own sentence when it gave one;
|
|
180
|
+
* - `unreadable`: a success whose body is not an answer this CLI can read;
|
|
181
|
+
* - `unreachable`: the service could not be reached at all.
|
|
182
|
+
*/
|
|
183
|
+
export type ReviewOpenAnswer = {
|
|
184
|
+
kind: 'answered';
|
|
185
|
+
answer: OpenReviewAnswer;
|
|
186
|
+
} | {
|
|
187
|
+
kind: 'refused';
|
|
188
|
+
status: number;
|
|
189
|
+
message: string | null;
|
|
190
|
+
} | {
|
|
191
|
+
kind: 'unreadable';
|
|
192
|
+
status: number;
|
|
193
|
+
} | {
|
|
194
|
+
kind: 'unreachable';
|
|
195
|
+
why: string;
|
|
196
|
+
};
|
|
197
|
+
/** What one run of the close step did: the count it sent, the commit it read, the answer. */
|
|
198
|
+
export interface ReviewOpenAttempt {
|
|
199
|
+
observe: ObserveRunResult;
|
|
200
|
+
closeCommit: CloseCommitOutcome;
|
|
201
|
+
open: ReviewOpenAnswer;
|
|
202
|
+
}
|
|
203
|
+
/** What the close step sends: who ran it, the walk's outcome, and the client's statements. */
|
|
204
|
+
export interface CloseStepRequest {
|
|
205
|
+
actor: string;
|
|
206
|
+
acceptanceOutcome: AcceptanceOutcome;
|
|
207
|
+
stated: StatedStatements;
|
|
208
|
+
}
|
|
209
|
+
/** The address of a phase's open route: the phase is one path segment, encoded once. */
|
|
210
|
+
export declare function reviewOpenUrl(credential: RepoCredential, phase: string): string;
|
|
211
|
+
/**
|
|
212
|
+
* Run the close step: check the request, read HEAD, send a fresh count through
|
|
213
|
+
* `observe`, then ask the service to open the review of `phase`.
|
|
161
214
|
*
|
|
162
|
-
* @param
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* close is unreachable from any caller that compiles.
|
|
169
|
-
* @param repoRoot the repository whose HEAD this close is sent with.
|
|
170
|
-
* Optional so that a caller with no repository in hand — a test
|
|
171
|
-
* harness, a future non-repo surface — is not forced to invent one;
|
|
172
|
-
* omitting it sends no commit rather than silently resolving the
|
|
215
|
+
* @param observe the fresh count, run after the request is checked and before the open
|
|
216
|
+
* is sent. The CLI passes `runObserveChild` over the shipped runner
|
|
217
|
+
* binary; it is a parameter so this function holds no path to a binary
|
|
218
|
+
* of its own.
|
|
219
|
+
* @param repoRoot the repository whose HEAD the statements carry. Optional so a caller
|
|
220
|
+
* with no repository in hand sends no commit rather than resolving the
|
|
173
221
|
* process's working directory, which would send a stranger's HEAD.
|
|
174
|
-
* @param stated the client's own statements; each absent one is sent as not
|
|
175
|
-
* stated (`null`, or no deviations).
|
|
176
222
|
*
|
|
177
|
-
* @throws
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
|
|
223
|
+
* @throws CloseRequestInvalid before anything is sent — no count and no open — when the
|
|
224
|
+
* request fails the shared schema or the phase is not a phase name (the one
|
|
225
|
+
* rule, `phaseNameSchema`); nothing else is thrown — every answer is an outcome.
|
|
226
|
+
*/
|
|
227
|
+
export declare function openPhaseReview(credential: RepoCredential, phase: string, request: CloseStepRequest, observe: () => Promise<ObserveRunResult>, repoRoot?: string): Promise<ReviewOpenAttempt>;
|
|
228
|
+
/** CL1 — the review is open. */
|
|
229
|
+
export declare function reviewOpenedLine(phase: string): string;
|
|
230
|
+
/** CL2 — Halfcycle could not count what the phase changed. */
|
|
231
|
+
export declare const COULD_NOT_COUNT_LINE = "[halfcycle] Halfcycle could not count what this phase changed, so the owner judges each part on what the agents reported alone.";
|
|
232
|
+
/** H1 (`typed-close-review`) — how the owner reviews, or that typing is switched off. */
|
|
233
|
+
export declare function typedReviewHintLine(offered: boolean): string;
|
|
234
|
+
/** CL3 — tasks of the phase are not finished, named by title, at most ten. */
|
|
235
|
+
export declare function tasksOpenLine(phase: string, open: readonly string[], more: number): string;
|
|
236
|
+
/** CL4 — no build of the phase has been reported. */
|
|
237
|
+
export declare function noBuildLine(phase: string): string;
|
|
238
|
+
/** CL5 — a round is already open and waiting for the owner. */
|
|
239
|
+
export declare function reviewAlreadyOpenLine(phase: string): string;
|
|
240
|
+
/**
|
|
241
|
+
* CL6 — steps of the phase are unfinished: the first line names each with its state,
|
|
242
|
+
* then one line per step from `unfinishedStepLine` (the one composer the typed review
|
|
243
|
+
* prints too), then what to run after.
|
|
244
|
+
*/
|
|
245
|
+
export declare function unfinishedStepsLines(phase: string, steps: Parameters<typeof unfinishedStepLine>[0][]): string[];
|
|
246
|
+
/** CL12 — a clean verdict over defects recorded against the phase. */
|
|
247
|
+
export declare function cleanOverFindingsLine(phase: string, findings: number): string;
|
|
248
|
+
/** What the close step prints for one attempt, and the exit code it ends with. */
|
|
249
|
+
export interface CloseStepReport {
|
|
250
|
+
stdout: string[];
|
|
251
|
+
stderr: string[];
|
|
252
|
+
exitCode: 0 | 1;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Every line the close step prints for one attempt. An open prints CL1, then CL2 when
|
|
256
|
+
* the answer says Halfcycle could not count, then H1, and closes nothing; a commit
|
|
257
|
+
* that could not be read is then said on stderr, with the reasons this verb has always
|
|
258
|
+
* given (git missing and git's bad answer stay two), because the statements carry the
|
|
259
|
+
* commit to the record. A refusal from the service names each field by its flag, as a
|
|
260
|
+
* refusal on this machine does (`describeIssuePath`). A refusal prints
|
|
261
|
+
* its own sentence and exits 1.
|
|
181
262
|
*/
|
|
182
|
-
export declare function
|
|
263
|
+
export declare function closeStepReport(phase: string, attempt: ReviewOpenAttempt): CloseStepReport;
|
|
183
264
|
//# sourceMappingURL=close-phase.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"close-phase.d.ts","sourceRoot":"","sources":["../src/close-phase.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"close-phase.d.ts","sourceRoot":"","sources":["../src/close-phase.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EAQL,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElG;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4EAA4E;AAC5E,eAAO,MAAM,aAAa,EAAE,gBAAkE,CAAC;AAE/F;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GAAG,eAAe,GAAG,WAAW,GAAG,YAAY,CAAC;AAE3E,qFAAqF;AACrF,MAAM,MAAM,iBAAiB,GACzB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,eAAe,GAAG,WAAW,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAgC9E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,kBAAkB,CAkBhF;AAID;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B;;;;CAI/B,CAAC;AAKX;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,cAAc,GAAG,MAAM,CAAC,UAAU,CAM7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAUhE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,GAAG,KAAK,EACtB,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAuB3B;AAID;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,6FAA6F;AAC7F,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,EAAE,kBAAkB,CAAC;IAChC,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED,8FAA8F;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK/E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,cAAc,EAC1B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,EACxC,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,CAAC,CAkE5B;AA6BD,gCAAgC;AAChC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,oIACkG,CAAC;AAEpI,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAI5D;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAe1F;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,GAChD,MAAM,EAAE,CAOV;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI7E;AAED,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,eAAe,CA2E1F"}
|
package/dist/draw/index.d.ts
CHANGED
|
@@ -18,6 +18,17 @@
|
|
|
18
18
|
* just before writing, so a refusal this command can make locally never costs a
|
|
19
19
|
* request, and a change made while it waited is still seen.
|
|
20
20
|
*
|
|
21
|
+
* THE CLOSED ARM COMES FIRST, for a phase (`part-state-and-builds` AC5, #1742's forward
|
|
22
|
+
* close half). After the identity and flight-deck checks, `localRefusal` is asked once
|
|
23
|
+
* and the credential is read (`readCredentialOrLine`, `../system-report.ts`) before
|
|
24
|
+
* anything is sent — no description, no plan. `{ picture: 'closed-phase', phase }`
|
|
25
|
+
* is then sent alone. `drawn` is checked and written exactly as steps (4) and (5) above,
|
|
26
|
+
* and nothing else is sent: a closed phase needs no plan file and no fresh description.
|
|
27
|
+
* `refused` stops the verb with the service's reason. Anything else — `not-closed`, a
|
|
28
|
+
* missing route, or the service unavailable — runs the order above unchanged, from (1):
|
|
29
|
+
* a server that does not yet know this phase as closed, or does not know the arm at
|
|
30
|
+
* all, draws the phase exactly as it did before this spec.
|
|
31
|
+
*
|
|
21
32
|
* A PHASE'S FILES. The base name is `phaseDiagramBase(phase)`, `renderPhaseSegment`'s
|
|
22
33
|
* segment. A phase that is not a valid identity is refused naming it, before anything
|
|
23
34
|
* is read; so is one whose base name ends in the Flight Deck word, in any case, whose
|
|
@@ -32,15 +43,20 @@
|
|
|
32
43
|
* For a phase, the plan route and the draw route's phase arm ship in one service
|
|
33
44
|
* release, so a missing plan route is the one signal that this service cannot draw
|
|
34
45
|
* phase pictures, and the draw route is then never asked. Anything else is reported by
|
|
35
|
-
* its status and the service's own sentence.
|
|
46
|
+
* its status and the service's own sentence. The answer-parsing switch is exhaustive
|
|
47
|
+
* over `systemDrawResultSchema`'s four outcomes, with a `never` default (`assertNever`):
|
|
48
|
+
* a fifth outcome added to the wire without a matching case here is a compile error.
|
|
36
49
|
*
|
|
37
50
|
* NO BYTE OF THE RESPONSE DECIDES A PATH (INV-023): the response gives contents only;
|
|
38
51
|
* where they go is `./write.ts`'s constants and the base name this module chose from
|
|
39
52
|
* the arguments.
|
|
40
53
|
*
|
|
41
|
-
* WHAT LEAVES THE MACHINE.
|
|
42
|
-
*
|
|
43
|
-
* `{
|
|
54
|
+
* WHAT LEAVES THE MACHINE. For the architecture, the checked description (through the
|
|
55
|
+
* shared stage), then `{ version, picture: 'architecture' }`. For a phase, first
|
|
56
|
+
* `{ picture: 'closed-phase', phase }` alone; only once that answers `not-closed` (or a
|
|
57
|
+
* missing route, or the service is unavailable) does the checked description and the
|
|
58
|
+
* checked plan (through `plan`'s request) go out, then `{ picture: 'phase', phase,
|
|
59
|
+
* planVersion }`.
|
|
44
60
|
*
|
|
45
61
|
* INV-001: Node builtins, the global `fetch`, `@halfcycle/events` and `@halfcycle/core`
|
|
46
62
|
* only. SHIPS TO CLIENT DISK inside the CLI: every string here is a sentence a person
|
|
@@ -81,7 +97,9 @@ export declare function parseDrawArgs(argv: readonly string[]): DrawArgs;
|
|
|
81
97
|
* What came of asking for the drawing. `drawn`: the Mermaid and every look's picture,
|
|
82
98
|
* parsed under the strict result schema (so no look is missing and none is extra) but
|
|
83
99
|
* not yet checked. `refused`: the service's reason. `no-route`: this service cannot draw yet.
|
|
84
|
-
* `unavailable`: it could not be drawn, and `why` says so.
|
|
100
|
+
* `unavailable`: it could not be drawn, and `why` says so. `not-closed`: the answer to
|
|
101
|
+
* the closed arm alone (`part-state-and-builds` AC5) — the phase has not closed, or was
|
|
102
|
+
* opened again since, so the caller draws it as it stands now with the `phase` arm.
|
|
85
103
|
*/
|
|
86
104
|
export type DrawOutcome = {
|
|
87
105
|
kind: 'drawn';
|
|
@@ -94,6 +112,8 @@ export type DrawOutcome = {
|
|
|
94
112
|
} | {
|
|
95
113
|
kind: 'unavailable';
|
|
96
114
|
why: string;
|
|
115
|
+
} | {
|
|
116
|
+
kind: 'not-closed';
|
|
97
117
|
};
|
|
98
118
|
/** The address the drawing is asked of: the engagement is one path segment, encoded once. */
|
|
99
119
|
export declare function systemDrawUrl(credential: RepoCredential): string;
|
package/dist/draw/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/draw/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/draw/index.ts"],"names":[],"mappings":"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"}
|
package/dist/identity.d.ts
CHANGED
|
@@ -83,6 +83,38 @@ export declare function isGitWorkTree(targetRepoRoot: string): boolean;
|
|
|
83
83
|
export declare function gitIsInstalled(): boolean;
|
|
84
84
|
/** Read the `origin` remote URL. */
|
|
85
85
|
export declare function readRemote(targetRepoRoot: string): string | null;
|
|
86
|
+
/**
|
|
87
|
+
* Remove a password or token from a git remote, leaving the host and path
|
|
88
|
+
* (#1744: `project.json` is committed, so a remote embedding one — a common
|
|
89
|
+
* setup, our own clones have one — put it into the client's repository history
|
|
90
|
+
* and onto GitHub with the next push). `null` passes through unchanged.
|
|
91
|
+
*
|
|
92
|
+
* Both forms git itself accepts are covered, and they are NOT treated alike,
|
|
93
|
+
* because a bare user name means two different things in them:
|
|
94
|
+
*
|
|
95
|
+
* - A URL (`scheme://[user[:pass]@]host[:port]/path` — this also covers
|
|
96
|
+
* `ssh://`) is handed to the platform's own `URL` parser, which strips
|
|
97
|
+
* BOTH username and password whenever either is present. A bare username
|
|
98
|
+
* with no password is included on purpose: GitHub and most hosts accept a
|
|
99
|
+
* personal access token AS the username on an `https://` remote (`https://
|
|
100
|
+
* <token>@host/...`), which is exactly the shape that needs catching with
|
|
101
|
+
* no password field to key off. **When `URL` refuses to parse the string
|
|
102
|
+
* at all** (review R-34, F2 — a non-numeric port is a real remote `git`
|
|
103
|
+
* accepts and `URL` does not), the userinfo is stripped TEXTUALLY instead
|
|
104
|
+
* of leaving the input, credential and all, untouched.
|
|
105
|
+
* - The scp-like syntax git also accepts, with no scheme
|
|
106
|
+
* (`[user[:pass]@]host:path`, e.g. `git@github.com:org/repo.git`), has no
|
|
107
|
+
* parser to borrow, so it is read directly. There a bare username is not a
|
|
108
|
+
* secret — SSH carries no password in the URL at all, and `git@host:path`
|
|
109
|
+
* (or any fixed service account name) is the ordinary, universal shape of
|
|
110
|
+
* an SSH git remote, not a credential. So only a PASSWORD inside the
|
|
111
|
+
* userinfo (`user:pass@host:path`) is stripped here; a bare `user@` is
|
|
112
|
+
* left alone, or every ordinary SSH remote would be rewritten for nothing
|
|
113
|
+
* it is hiding. Split on the LAST `@` before the host (review R-34, F3): a
|
|
114
|
+
* password containing `@` (`user:p@ss@host:path`) made the first `@` leave
|
|
115
|
+
* a password FRAGMENT (`ss@host:path`) in the stored value.
|
|
116
|
+
*/
|
|
117
|
+
export declare function redactRemoteCredential(remote: string | null): string | null;
|
|
86
118
|
/**
|
|
87
119
|
* How many commits are reachable from HEAD, or `null` when this is not a git repository
|
|
88
120
|
* (or is one with no commits yet).
|
|
@@ -139,21 +171,58 @@ export declare function readIgnoredPaths(targetRepoRoot: string, paths: readonly
|
|
|
139
171
|
* on both the mint and the read path, so an install from before this field
|
|
140
172
|
* existed picks up the disambiguation text on its next install rather than
|
|
141
173
|
* staying silent forever.
|
|
174
|
+
*
|
|
175
|
+
* `remote` gets a second exception (#1744, decided G1): a file written before this
|
|
176
|
+
* fix existed may hold a remote with a credential in it. `repairRemoteCredential`
|
|
177
|
+
* below is called first, so by the time this function does its own read the file
|
|
178
|
+
* is already clean on disk when that write could land; `redactRemoteCredential`
|
|
179
|
+
* is then applied to the in-memory value too, so what this function RETURNS is
|
|
180
|
+
* clean even on a folder the repair could not write to.
|
|
142
181
|
*/
|
|
143
182
|
export declare function mintOrReadIdentity(targetRepoRoot: string): {
|
|
144
183
|
identity: ProjectIdentity;
|
|
145
184
|
minted: boolean;
|
|
146
185
|
};
|
|
147
186
|
/**
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
187
|
+
* If `.halfcycle/project.json` exists and its `remote` still carries a credential,
|
|
188
|
+
* rewrite the file with it stripped — ONCE; a file whose remote is already clean
|
|
189
|
+
* is never touched. This is the G1 repair (#1744), and it is the ONE exception to
|
|
190
|
+
* "an existing `project.json` is never rewritten" (`createProjectIdentityFile`,
|
|
191
|
+
* the `note` field on `mintOrReadIdentity` above): every other path in this
|
|
192
|
+
* module leaves a present file alone, whatever its bytes.
|
|
193
|
+
*
|
|
194
|
+
* **CALLED FROM EVERY REAL PATH THAT TOUCHES AN EXISTING `project.json`, NOT
|
|
195
|
+
* ONLY FROM `mintOrReadIdentity` (review R-34, F1).** The first version of this
|
|
196
|
+
* fix lived entirely inside `mintOrReadIdentity`, which no production code
|
|
197
|
+
* calls — `install.ts`'s `writeProjectIdentity` and `pre-create-checks.ts`'s
|
|
198
|
+
* `claimFolderId` both skip a `project.json` that is already there and neither
|
|
199
|
+
* read it back, so a real `npx halfcycle` run left the credential in place.
|
|
200
|
+
* Those two call this function directly; `mintOrReadIdentity` calls it too, for
|
|
201
|
+
* every OTHER caller that reads the committed identity.
|
|
202
|
+
*
|
|
203
|
+
* Silently best-effort throughout: an unreadable file, one that is not valid
|
|
204
|
+
* JSON, or one that parses to something other than an object (`null`, an array,
|
|
205
|
+
* a bare string or number — `project-identity-reuse` AC2's "not an object" case,
|
|
206
|
+
* which this function must leave exactly as it was, same as its sibling
|
|
207
|
+
* refusal), or a folder this process cannot write to, is left exactly as it is
|
|
208
|
+
* for the next run to try again — a repair is not what the person asked this
|
|
209
|
+
* run to do, and must never be what makes it fail, let alone throw. Written to
|
|
210
|
+
* a temporary file beside the target first and renamed over it, so a reader
|
|
211
|
+
* never sees a half-written file.
|
|
212
|
+
*/
|
|
213
|
+
export declare function repairRemoteCredential(targetRepoRoot: string): void;
|
|
214
|
+
/**
|
|
215
|
+
* The ONE serializer for `project.json`. `createProjectIdentityFile` below calls
|
|
216
|
+
* it to produce the bytes for a freshly minted identity; `repairRemoteCredential`
|
|
217
|
+
* above calls it for the one other case this module ever writes an identity's
|
|
218
|
+
* bytes, the G1 credential repair (#1744). `install()`'s `writeProjectIdentity`
|
|
219
|
+
* no longer reconciles bytes itself — until the onboarding fix wave (T-05, from
|
|
220
|
+
* review R-03) it did, rewriting any file that differed from what it would have
|
|
221
|
+
* written (an older file without `note`, CRLF, an extra field). That
|
|
222
|
+
* reconciliation is retired: an existing file is skipped, whatever its bytes
|
|
223
|
+
* (`project-identity-reuse` AC1), with exactly one exception now — a credential
|
|
224
|
+
* in `remote`, which `writeProjectIdentity` repairs through the function below
|
|
225
|
+
* before reporting `skipped`.
|
|
157
226
|
*/
|
|
158
227
|
export declare function serializeProjectIdentity(identity: ProjectIdentity): string;
|
|
159
228
|
/**
|
package/dist/identity.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAeH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,qBAAqB,QAGF,CAAC;AAEjC,uFAAuF;AACvF,eAAO,MAAM,oBAAoB,4BAA4B,CAAC;AAE9D,kFAAkF;AAClF,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AA6BD,gFAAgF;AAChF,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,UAAU,CAItD;AAqBD,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMpE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAOxC;AAED,oCAAoC;AACpC,wBAAgB,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEhE;AA0BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAmB3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKrE;AAED,2DAA2D;AAC3D,MAAM,WAAW,WAAW;IAC1B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,CAyBvG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAczG;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,sBAAsB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CA4BnE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAE1E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAiBtE"}
|