halfcycle 0.4.4 → 0.4.6
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 +41 -26
- package/dist/bin.d.ts +2 -0
- package/dist/bin.d.ts.map +1 -1
- package/dist/build-record/obtain.d.ts +3 -1
- package/dist/build-record/obtain.d.ts.map +1 -1
- package/dist/build-record/write.d.ts +5 -1
- package/dist/build-record/write.d.ts.map +1 -1
- package/dist/cli-contract.d.ts +1 -1
- package/dist/cli-contract.d.ts.map +1 -1
- package/dist/cli.js +1178 -85
- package/dist/cli.js.map +3 -3
- package/dist/draw/index.d.ts +91 -0
- package/dist/draw/index.d.ts.map +1 -0
- package/dist/draw/write.d.ts +232 -0
- package/dist/draw/write.d.ts.map +1 -0
- package/dist/index.js +27 -11
- package/dist/index.js.map +3 -3
- package/dist/install.d.ts.map +1 -1
- package/dist/missing-route.d.ts +36 -0
- package/dist/missing-route.d.ts.map +1 -0
- package/dist/system-report.d.ts +168 -0
- package/dist/system-report.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The client half of `npx halfcycle@latest system` (System view · E1, feature
|
|
3
|
+
* `system-description`): read the project's `docs/system.json`, check it with the one
|
|
4
|
+
* shared check, warn about owned patterns that match no tracked file, and report it
|
|
5
|
+
* to the Halfcycle service, which answers with the version it holds.
|
|
6
|
+
*
|
|
7
|
+
* ONE HOME FOR EVERY RULE THIS VERB APPLIES (INV-003). The shape, the cross-field
|
|
8
|
+
* rules and the ownership grammar are `@halfcycle/events`' `checkSystemDescription`
|
|
9
|
+
* and `ownerOf` — this module calls them and restates none of them. The unowned-
|
|
10
|
+
* pattern warning asks `ownerOf` of a one-part, one-pattern description per pattern
|
|
11
|
+
* rather than matching paths itself, so "does this pattern own this file" has exactly
|
|
12
|
+
* one implementation, the one E3's counting uses. The answer's shape is the events
|
|
13
|
+
* package's `systemReportResultSchema`. "Is this a service without the route" is
|
|
14
|
+
* `isMissingRoute` (`./missing-route.ts`), shared with `build-record` and `draw`.
|
|
15
|
+
* `draw` takes this module's first stage, `checkAndReportDescription`, whole: the
|
|
16
|
+
* two verbs read, check and report the description by one path, not two copies.
|
|
17
|
+
*
|
|
18
|
+
* ONE RESPONSE-HANDLING RULE, the Build Record path's. A body that parses under
|
|
19
|
+
* `systemReportResultSchema` is authoritative, whatever its status. Otherwise the
|
|
20
|
+
* service's missing-route answer to a POST means it predates the route; anything
|
|
21
|
+
* else is reported by its status and the service's own sentence.
|
|
22
|
+
*
|
|
23
|
+
* WHAT LEAVES THE MACHINE. Only the description, and only after it passed the check.
|
|
24
|
+
* The tracked-file list read for the warning is a local read: nothing it finds is
|
|
25
|
+
* sent, and it sets nothing (INV-021). Nothing here writes into the person's tree.
|
|
26
|
+
*
|
|
27
|
+
* INV-001: Node builtins, the global `fetch`, `@halfcycle/events` and
|
|
28
|
+
* `@halfcycle/core` (through the shared credential and command helpers) only.
|
|
29
|
+
* SHIPS TO CLIENT DISK inside the CLI: every string here is a sentence a person
|
|
30
|
+
* reads, so none names an internal register, route or setting; no comment sits
|
|
31
|
+
* beside an object member.
|
|
32
|
+
*/
|
|
33
|
+
import { type SystemDescription, type SystemDescriptionProblem } from '@halfcycle/events';
|
|
34
|
+
import type { RepoCredential } from './open-phase.js';
|
|
35
|
+
/** Where the description lives, relative to the repository root. */
|
|
36
|
+
export declare const SYSTEM_DESCRIPTION_REL = "docs/system.json";
|
|
37
|
+
/**
|
|
38
|
+
* What reading `docs/system.json` came to. `missing`: there is no such file.
|
|
39
|
+
* `unreadable`: something is there and could not be read as a file. `not-json`: it
|
|
40
|
+
* was read and does not parse; `error` is the parser's own sentence. `read`: the
|
|
41
|
+
* parsed value, not yet checked.
|
|
42
|
+
*/
|
|
43
|
+
export type DescriptionFile = {
|
|
44
|
+
kind: 'missing';
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'unreadable';
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'not-json';
|
|
49
|
+
error: string;
|
|
50
|
+
} | {
|
|
51
|
+
kind: 'read';
|
|
52
|
+
value: unknown;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Read and parse the description under `repoRoot`. Never throws. A missing file is
|
|
56
|
+
* told apart from an unreadable one because the remedies differ: the first is
|
|
57
|
+
* written by the method's architecture step, the second is the person's to fix.
|
|
58
|
+
*/
|
|
59
|
+
export declare function readDescriptionFile(repoRoot: string): DescriptionFile;
|
|
60
|
+
/**
|
|
61
|
+
* A problem's place in words a person can find in their file: the dotted path the
|
|
62
|
+
* check reports (`parts.3.name`), then the part or connection it is in, named by its
|
|
63
|
+
* id or its ends when the raw value carries them, by its position otherwise.
|
|
64
|
+
*/
|
|
65
|
+
export declare function problemPlace(raw: unknown, path: string): string;
|
|
66
|
+
/** One line per problem, each naming where it is, for the terminal. */
|
|
67
|
+
export declare function problemLines(raw: unknown, problems: readonly SystemDescriptionProblem[]): string;
|
|
68
|
+
/** An owned pattern that matches no file git tracks, and the part that lists it. */
|
|
69
|
+
export interface UnownedPattern {
|
|
70
|
+
readonly partId: string;
|
|
71
|
+
readonly pattern: string;
|
|
72
|
+
}
|
|
73
|
+
/** How the tracked-file list is obtained; replaced in tests. `null` when there is none. */
|
|
74
|
+
export type ListTrackedFiles = (repoRoot: string) => string[] | null;
|
|
75
|
+
/**
|
|
76
|
+
* The files git tracks under `repoRoot`, as `git ls-files -z` prints them (relative,
|
|
77
|
+
* `/`-separated, unquoted), or `null` when there is no git, `repoRoot` is not inside
|
|
78
|
+
* a repository, or the list could not be read. The repository-locating variables are
|
|
79
|
+
* removed from git's environment so the folder named is the one read.
|
|
80
|
+
*/
|
|
81
|
+
export declare const listTrackedFiles: ListTrackedFiles;
|
|
82
|
+
/**
|
|
83
|
+
* The owned patterns that match no tracked file — how a description drifts from the
|
|
84
|
+
* code. A warning, never a refusal. `null` when the tracked-file list is unavailable:
|
|
85
|
+
* the warning is then skipped, not guessed.
|
|
86
|
+
*
|
|
87
|
+
* Each pattern is asked of `ownerOf` on its own (a description holding just that part
|
|
88
|
+
* with just that pattern), so a pattern another part outranks on every file still
|
|
89
|
+
* counts as matching: the warning is about patterns that name nothing, not about
|
|
90
|
+
* ranking.
|
|
91
|
+
*/
|
|
92
|
+
export declare function unownedPatterns(description: SystemDescription, tracked: readonly string[] | null): UnownedPattern[] | null;
|
|
93
|
+
/** The warning lines for unowned patterns, one per pattern. */
|
|
94
|
+
export declare function unownedPatternLines(unowned: readonly UnownedPattern[]): string;
|
|
95
|
+
/**
|
|
96
|
+
* What came of reporting the description. `recorded`: the service holds it as
|
|
97
|
+
* `version` (a description it already had returns that version). `refused`: the
|
|
98
|
+
* service's own problems. `no-route`: this service cannot take a description yet.
|
|
99
|
+
* `unavailable`: it could not be reported, and `why` says so.
|
|
100
|
+
*/
|
|
101
|
+
export type ReportOutcome = {
|
|
102
|
+
kind: 'recorded';
|
|
103
|
+
version: number;
|
|
104
|
+
reportedAt: string;
|
|
105
|
+
} | {
|
|
106
|
+
kind: 'refused';
|
|
107
|
+
problems: SystemDescriptionProblem[];
|
|
108
|
+
} | {
|
|
109
|
+
kind: 'no-route';
|
|
110
|
+
} | {
|
|
111
|
+
kind: 'unavailable';
|
|
112
|
+
why: string;
|
|
113
|
+
};
|
|
114
|
+
/** The address the description is reported to: the engagement is one path segment, encoded once. */
|
|
115
|
+
export declare function systemReportUrl(credential: RepoCredential): string;
|
|
116
|
+
/**
|
|
117
|
+
* Report a checked description. Never throws: the network, the service and an answer
|
|
118
|
+
* this CLI cannot read are each an outcome the caller prints.
|
|
119
|
+
*/
|
|
120
|
+
export declare function reportSystemDescription(credential: RepoCredential, description: SystemDescription): Promise<ReportOutcome>;
|
|
121
|
+
/** What `system` prints and the exit code it ends with. */
|
|
122
|
+
export interface SystemRun {
|
|
123
|
+
readonly stdout: string;
|
|
124
|
+
readonly stderr: string;
|
|
125
|
+
readonly exitCode: 0 | 1;
|
|
126
|
+
}
|
|
127
|
+
/** The pieces `runSystem` reaches outside itself through; replaced in tests. */
|
|
128
|
+
export interface SystemDeps {
|
|
129
|
+
readonly readCredential: (repoRoot: string) => RepoCredential;
|
|
130
|
+
readonly listTracked: ListTrackedFiles;
|
|
131
|
+
readonly report: (credential: RepoCredential, description: SystemDescription) => Promise<ReportOutcome>;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* What the shared first stage came to. `stopped`: the verb ends here and `stderr` is
|
|
135
|
+
* the whole of what it prints. `no-route`: the service cannot take a description yet;
|
|
136
|
+
* the caller words that for its own verb. `recorded`: the service holds the checked
|
|
137
|
+
* description as `version`, and `credential` is the one it was reported with.
|
|
138
|
+
* `warnings` is the unowned-pattern lines, printed whatever the caller does next.
|
|
139
|
+
*/
|
|
140
|
+
export type DescriptionStage = {
|
|
141
|
+
kind: 'stopped';
|
|
142
|
+
stderr: string;
|
|
143
|
+
} | {
|
|
144
|
+
kind: 'no-route';
|
|
145
|
+
warnings: string;
|
|
146
|
+
} | {
|
|
147
|
+
kind: 'recorded';
|
|
148
|
+
version: number;
|
|
149
|
+
credential: RepoCredential;
|
|
150
|
+
warnings: string;
|
|
151
|
+
};
|
|
152
|
+
/** The verbs that report the description first. Names the prefix of every line. */
|
|
153
|
+
export type DescriptionVerb = 'system' | 'draw';
|
|
154
|
+
/**
|
|
155
|
+
* READ, CHECK, WARN, REPORT — the one path both `system` and `draw` take before
|
|
156
|
+
* anything else (feature `diagram-files-for-docs`, step 1 and 2 of the command). The
|
|
157
|
+
* order is the spec's: nothing is sent unless the file reads, parses and passes every
|
|
158
|
+
* rule, and the credential is only looked for once there is something to send.
|
|
159
|
+
*
|
|
160
|
+
* `beforeSend` is the caller's own local refusal, asked after the description passed
|
|
161
|
+
* and before the credential is read or anything sent: `draw` refuses there when a file
|
|
162
|
+
* it does not own is in the way, so a refusal it can make on the machine never costs a
|
|
163
|
+
* request. It returns the line to print, or `null` to go on.
|
|
164
|
+
*/
|
|
165
|
+
export declare function checkAndReportDescription(repoRoot: string, deps: SystemDeps, verb: DescriptionVerb, beforeSend?: () => string | null): Promise<DescriptionStage>;
|
|
166
|
+
/** The whole `system` verb: the shared stage, then its version printed. */
|
|
167
|
+
export declare function runSystem(repoRoot: string, deps: SystemDeps): Promise<SystemRun>;
|
|
168
|
+
//# sourceMappingURL=system-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-report.d.ts","sourceRoot":"","sources":["../src/system-report.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED