@descent-vtt/spec-harness 0.18.0 → 0.20.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +372 -0
- package/README.md +78 -11
- package/dist/briefs.d.ts +45 -0
- package/dist/briefs.js +73 -0
- package/dist/briefs.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +384 -84
- package/dist/cli.js.map +1 -1
- package/dist/commands.js +7 -2
- package/dist/commands.js.map +1 -1
- package/dist/config.d.ts +15 -1
- package/dist/config.js +16 -3
- package/dist/config.js.map +1 -1
- package/dist/configure.d.ts +142 -32
- package/dist/configure.js +316 -89
- package/dist/configure.js.map +1 -1
- package/dist/fs.d.ts +150 -3
- package/dist/fs.js +459 -17
- package/dist/fs.js.map +1 -1
- package/dist/git.d.ts +85 -9
- package/dist/git.js +140 -16
- package/dist/git.js.map +1 -1
- package/dist/hooks.d.ts +111 -0
- package/dist/hooks.js +172 -16
- package/dist/hooks.js.map +1 -1
- package/dist/round.d.ts +8 -0
- package/dist/round.js +32 -9
- package/dist/round.js.map +1 -1
- package/dist/sandbox.js +4 -3
- package/dist/sandbox.js.map +1 -1
- package/dist/server.d.ts +25 -1
- package/dist/server.js +194 -27
- package/dist/server.js.map +1 -1
- package/dist/setup.d.ts +6 -3
- package/dist/setup.js +74 -23
- package/dist/setup.js.map +1 -1
- package/dist/siblings.d.ts +42 -7
- package/dist/siblings.js +135 -30
- package/dist/siblings.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.js.map +1 -1
- package/dist/usage.d.ts +66 -12
- package/dist/usage.js +134 -21
- package/dist/usage.js.map +1 -1
- package/dist/workspace.d.ts +80 -1
- package/dist/workspace.js +188 -8
- package/dist/workspace.js.map +1 -1
- package/hooks/hooks.json +16 -0
- package/package.json +2 -2
package/dist/fs.d.ts
CHANGED
|
@@ -2,12 +2,49 @@
|
|
|
2
2
|
* The edge where the harness meets the disk: the configuration, the state
|
|
3
3
|
* directory outside the work tree, and paths as the filesystem spells them.
|
|
4
4
|
*/
|
|
5
|
+
import type { BriefInputs } from './briefs.js';
|
|
5
6
|
import { type HarnessConfig } from './config.js';
|
|
6
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Whether a regular file stands at a path, links followed. Only one is read
|
|
9
|
+
* where a file is expected: opened, a named pipe nothing writes to is read
|
|
10
|
+
* without end, and one read as the process waits on it, as the harness reads
|
|
11
|
+
* a few small files, stops every timer with it (ADR-0002).
|
|
12
|
+
*/
|
|
13
|
+
export declare function isFile(path: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Reads `.spec-harness.json` at the root, or the defaults when there is none.
|
|
16
|
+
*
|
|
17
|
+
* Only a file is read. A named pipe under the file's name was read without
|
|
18
|
+
* end, by every command and by the hook before every write; and Node's words
|
|
19
|
+
* for a directory, EISDIR, are not the harness's. A file that cannot be read
|
|
20
|
+
* is said as that, with the reason: one the account may not read, or one
|
|
21
|
+
* another process holds open on Windows, was said to be JSON that is not
|
|
22
|
+
* valid, which sent a person to its text. What does not load is thrown with
|
|
23
|
+
* the path it stands at, which the hook lets a write reach (ADR-0005).
|
|
24
|
+
*/
|
|
7
25
|
export declare function loadConfig(root: string): Promise<{
|
|
8
26
|
config: HarnessConfig;
|
|
9
27
|
file: string | null;
|
|
10
28
|
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Whether every path of a write names `file` and nothing else: a file that
|
|
31
|
+
* stands under that name alone, which the path names as the hook resolves a
|
|
32
|
+
* path to decide it ({@link realSpelling}), and as the filesystem resolves
|
|
33
|
+
* it to write, which on Linux and macOS follows a link before a `..` where
|
|
34
|
+
* the hook reads the `..` first. A path that only reads like it, a link to
|
|
35
|
+
* it, a second name of it, and a file of another work tree are none of
|
|
36
|
+
* these. `cwd` is what a relative path is read from, its words kept as
|
|
37
|
+
* written.
|
|
38
|
+
*/
|
|
39
|
+
export declare function writesOnly(paths: readonly string[], file: string, cwd: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* A path where the harness keeps its state that holds something else: said
|
|
42
|
+
* in a line, exit 2, where Node's ENOTDIR and a stack sent a person looking
|
|
43
|
+
* for a defect (spec-core ADR-0005).
|
|
44
|
+
*/
|
|
45
|
+
export declare class StateError extends Error {
|
|
46
|
+
constructor(message: string);
|
|
47
|
+
}
|
|
11
48
|
/**
|
|
12
49
|
* The real spelling of a path: links resolved and, on a filesystem that
|
|
13
50
|
* ignores case, the case the directory entries have. A path that does not
|
|
@@ -25,6 +62,15 @@ export declare function realSpelling(path: string): string;
|
|
|
25
62
|
* for what it would say from the other.
|
|
26
63
|
*/
|
|
27
64
|
export declare function isTop(directory: string, top: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* The repository's main work tree, where git keeps the repository as that
|
|
67
|
+
* work tree's `.git`, as `git init` and `git clone` do and every linked
|
|
68
|
+
* worktree's common directory then is: `null` for a common directory of any
|
|
69
|
+
* other name, a bare repository's, a submodule's under its superproject's
|
|
70
|
+
* `modules`, or one kept apart with `--separate-git-dir`. Read from the
|
|
71
|
+
* name, with no process: it says only where an install is looked for.
|
|
72
|
+
*/
|
|
73
|
+
export declare function mainWorkTree(commonDir: string): string | null;
|
|
28
74
|
/** Whether a `.git` stands in `directory`, a repository's or the file that names one, as at the top of a work tree. */
|
|
29
75
|
export declare function holdsGit(directory: string): boolean;
|
|
30
76
|
/**
|
|
@@ -32,12 +78,113 @@ export declare function holdsGit(directory: string): boolean;
|
|
|
32
78
|
* real spelling - or `null` when it lies outside the root.
|
|
33
79
|
*/
|
|
34
80
|
export declare function repositoryPath(given: string, root: string, cwd: string): string | null;
|
|
35
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* The top of every work tree of the repository whose common directory is
|
|
83
|
+
* `common`, `top` among them, read with no process: the main work tree,
|
|
84
|
+
* whose `.git` the common directory is, and each linked worktree, by the
|
|
85
|
+
* `gitdir` file git keeps for it under the common directory's `worktrees`,
|
|
86
|
+
* which names the worktree's `.git` (gitrepository-layout(5)), absolute or
|
|
87
|
+
* from its own directory. `null` where they cannot all be named: a common
|
|
88
|
+
* directory of any other name, whose main work tree only its configuration
|
|
89
|
+
* names, and an entry under `worktrees` that cannot be read.
|
|
90
|
+
*/
|
|
91
|
+
export declare function workTrees(top: string, common: string): string[] | null;
|
|
92
|
+
/**
|
|
93
|
+
* Whether every path lies outside every work tree of the repository whose
|
|
94
|
+
* top and common directory are given: such a path is no file of the
|
|
95
|
+
* repository's, so no brief of its decides it, whatever is wrong with the
|
|
96
|
+
* brief or the configuration (ADR-0005). Where the work trees cannot all
|
|
97
|
+
* be named, a path is not known to be outside them, and this is `false`.
|
|
98
|
+
*/
|
|
99
|
+
export declare function outsideEvery(paths: readonly string[], top: string, common: string, cwd: string): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* The harness's own directory under the git common directory, created on
|
|
102
|
+
* demand (ADR-0003). Where something that is no directory stands at its path,
|
|
103
|
+
* or at one between it and git's, Node refuses to make it, with ENOTDIR or
|
|
104
|
+
* EEXIST, and the harness says which path holds what.
|
|
105
|
+
*/
|
|
36
106
|
export declare function stateDirectory(commonDir: string, ...parts: string[]): Promise<string>;
|
|
107
|
+
/**
|
|
108
|
+
* A work tree and its git directories as the files git keeps name them, read
|
|
109
|
+
* with no process: the nearest directory at or above `root` that holds a
|
|
110
|
+
* `.git`; the git directory, that `.git` or the one a `.git` file names
|
|
111
|
+
* (`gitdir: <path>`, relative to the file's directory); and the common
|
|
112
|
+
* directory, the one that git directory's `commondir` file names, relative
|
|
113
|
+
* to it, or the git directory itself (gitrepository-layout(5)). `exact` is
|
|
114
|
+
* whether git, asked, would name the same work tree: not where
|
|
115
|
+
* `GIT_DIR` or `GIT_WORK_TREE` sends it elsewhere, and not where the
|
|
116
|
+
* repository's configuration names a `worktree`, which `core.worktree`
|
|
117
|
+
* moves it to (git-config(1)), or keeps one of its own for a worktree.
|
|
118
|
+
* `null` where no directory up to the top of the filesystem holds one, or
|
|
119
|
+
* a `.git` file names none.
|
|
120
|
+
*/
|
|
121
|
+
export declare function gitDirectories(root: string, env: Readonly<Record<string, string | undefined>>): {
|
|
122
|
+
readonly top: string;
|
|
123
|
+
readonly git: string;
|
|
124
|
+
readonly common: string;
|
|
125
|
+
readonly exact: boolean;
|
|
126
|
+
} | null;
|
|
127
|
+
/**
|
|
128
|
+
* How long a call's decisions are kept for a run after the write that does
|
|
129
|
+
* not come: a call refused by the person, one that failed, one stopped
|
|
130
|
+
* (ADR-0002). A day, since a call waits on a person's prompt for as long as
|
|
131
|
+
* the person is away, and an entry removed too soon costs only that call's
|
|
132
|
+
* answer being decided again.
|
|
133
|
+
*/
|
|
134
|
+
export declare const CALL_LIFE_MS: number;
|
|
135
|
+
/**
|
|
136
|
+
* Keeps what a run before a write decided, under the common directory, for
|
|
137
|
+
* the run after it, and removes what no run after a write read in a day.
|
|
138
|
+
* Nothing here may change the answer before the write: whatever fails is
|
|
139
|
+
* passed over, and the run after the write then decides as it did.
|
|
140
|
+
*/
|
|
141
|
+
export declare function keepCall(commonDir: string, name: string, text: string, now?: number): Promise<void>;
|
|
142
|
+
/** What was kept for a call, taken away as it is read; `null` where nothing was. */
|
|
143
|
+
export declare function takeCall(commonDir: string, name: string): Promise<string | null>;
|
|
144
|
+
/** SHA-256 of a text or of bytes, in hex. */
|
|
145
|
+
export type Hash = (data: string | Uint8Array) => string;
|
|
146
|
+
/** SHA-256, loaded where something is hashed: a run that keeps no answer loads no hash (ADR-0002). */
|
|
147
|
+
export declare function hasher(): Promise<Hash>;
|
|
148
|
+
/**
|
|
149
|
+
* How long a session's answer of spec-brief's is kept once it was last
|
|
150
|
+
* kept (ADR-0003). A day, as a call's: an answer removed costs one start of
|
|
151
|
+
* spec-brief, and one kept is a few kilobytes.
|
|
152
|
+
*/
|
|
153
|
+
export declare const ANSWER_LIFE_MS: number;
|
|
154
|
+
/**
|
|
155
|
+
* Keeps a session's answer of spec-brief's under the common directory, with
|
|
156
|
+
* the key it answers, and removes what was kept over a day ago. Whatever
|
|
157
|
+
* fails is passed over: the answer is the one given whether or not it is
|
|
158
|
+
* kept.
|
|
159
|
+
*/
|
|
160
|
+
export declare function keepAnswer(commonDir: string, name: string, key: string, answer: string, now?: number): Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* The answer kept under `name` for `key`, or `null` where there is none:
|
|
163
|
+
* nothing there, something that is not a file, a text that is not what
|
|
164
|
+
* `keepAnswer` writes, or another key's.
|
|
165
|
+
*/
|
|
166
|
+
export declare function keptAnswer(commonDir: string, name: string, key: string): Promise<string | null>;
|
|
167
|
+
/**
|
|
168
|
+
* Whether every input of an answer reads as listed, with no process
|
|
169
|
+
* started: each file by the digest of its bytes, or as not there; each
|
|
170
|
+
* directory by its entries; and, where git was asked, the index of the work
|
|
171
|
+
* tree's git directory and each ignore file. A path is read from the work
|
|
172
|
+
* tree's top, or as it stands where it is absolute. Anything that cannot be
|
|
173
|
+
* read, and an index that is not the one git reads for the work tree, is a
|
|
174
|
+
* doubt, and answers `false` (ADR-0002).
|
|
175
|
+
*/
|
|
176
|
+
export declare function readsAsListed(root: string, inputs: BriefInputs, hash: Hash, env?: Readonly<Record<string, string | undefined>>): Promise<boolean>;
|
|
37
177
|
/** Writes a file whole or not at all: a temporary file renamed over the target. */
|
|
38
178
|
export declare function writeAtomic(file: string, content: string): Promise<void>;
|
|
39
|
-
/**
|
|
179
|
+
/**
|
|
180
|
+
* A JSON object from a file: `null` when there is no file, `'unreadable'`
|
|
181
|
+
* when it holds anything else. Only a file is read: a named pipe where a
|
|
182
|
+
* settings file is expected was read without end, and neither doctor nor
|
|
183
|
+
* init came back. What is neither a file nor a directory holds no JSON
|
|
184
|
+
* object, as a directory holds none.
|
|
185
|
+
*/
|
|
40
186
|
export declare function readJsonObject(file: string): Promise<Record<string, unknown> | null | 'unreadable'>;
|
|
41
187
|
/** Whether a path names a directory that is there; one that cannot be read names none. */
|
|
42
188
|
export declare function isDirectory(path: string): boolean;
|
|
189
|
+
/** A file's text, or `null` where it cannot be read or is no file: a brief, a document one cites, a shim. */
|
|
43
190
|
export declare function readText(file: string): Promise<string | null>;
|