@orkestrel/scaffold 0.0.108 → 0.0.109
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/dist/agents/skills/orkestrel-dispatch/scripts/bench.js +326 -91
- package/dist/agents/skills/orkestrel-dispatch/scripts/brief.js +110 -14
- package/dist/agents/skills/orkestrel-dispatch/scripts/chain.js +280 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/cite.js +188 -26
- package/dist/agents/skills/orkestrel-dispatch/scripts/launch.js +142 -43
- package/dist/agents/skills/orkestrel-dispatch/scripts/login.js +240 -62
- package/dist/agents/skills/orkestrel-dispatch/scripts/patch.js +323 -0
- package/dist/agents/skills/orkestrel-dispatch/scripts/result.js +169 -32
- package/dist/agents/skills/orkestrel-dispatch/scripts/sweep.js +290 -69
- package/dist/agents/skills/orkestrel-falsify/scripts/mutate.js +560 -0
- package/dist/agents/skills/orkestrel-harden/scripts/discovery.js +1052 -205
- package/dist/agents/skills/orkestrel-harden/scripts/measure.js +361 -0
- package/dist/agents/skills/orkestrel-harden/scripts/titles.js +455 -80
- package/dist/agents/skills/orkestrel-parallel/scripts/cases.js +327 -0
- package/dist/agents/skills/orkestrel-publish/scripts/compare.js +298 -51
- package/dist/agents/skills/orkestrel-publish/scripts/pins.js +170 -13
- package/dist/agents/skills/orkestrel-publish/scripts/swap.js +956 -191
- package/dist/agents/skills/orkestrel-publish/scripts/wave.js +707 -112
- package/dist/agents/skills/orkestrel-publish/scripts/window.js +235 -41
- package/dist/agents/skills/orkestrel-scout/scripts/map.js +341 -54
- package/dist/agents/templates/brief.md +1 -1
- package/dist/bin/main.js +51 -46
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +23 -21
- package/dist/host/agents/orchestration.md +43 -18
- package/dist/host/agents/platforms/windows.md +3 -3
- package/dist/host/agents/skills/orkestrel-align/SKILL.md +10 -13
- package/dist/host/agents/skills/orkestrel-align/references/fleet.md +4 -10
- package/dist/host/agents/skills/orkestrel-align/references/integration.md +1 -1
- package/dist/host/agents/skills/orkestrel-build/SKILL.md +16 -48
- package/dist/host/agents/skills/orkestrel-build/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +19 -16
- package/dist/host/agents/skills/orkestrel-debrief/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +15 -28
- package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +5 -6
- package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +4 -6
- package/dist/host/agents/skills/orkestrel-dispatch/SKILL.md +31 -20
- package/dist/host/agents/skills/orkestrel-dispatch/references/launch.md +3 -4
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/bench.ts +366 -75
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/brief.ts +126 -16
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/chain.ts +323 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/cite.ts +220 -31
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/launch.ts +176 -33
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/login.ts +294 -59
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/patch.ts +401 -0
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/result.ts +199 -34
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/sweep.ts +330 -69
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +10 -8
- package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +1 -5
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +1 -1
- package/dist/host/agents/skills/orkestrel-falsify/scripts/mutate.ts +701 -0
- package/dist/host/agents/skills/orkestrel-harden/SKILL.md +16 -12
- package/dist/host/agents/skills/orkestrel-harden/references/bindings.md +23 -81
- package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +4 -5
- package/dist/host/agents/skills/orkestrel-harden/references/contract.md +2 -0
- package/dist/host/agents/skills/orkestrel-harden/references/document.md +33 -0
- package/dist/host/agents/skills/orkestrel-harden/references/equivalence.md +6 -3
- package/dist/host/agents/skills/orkestrel-harden/references/hardening.md +8 -4
- package/dist/host/agents/skills/orkestrel-harden/references/research.md +2 -0
- package/dist/host/agents/skills/orkestrel-harden/scripts/discovery.ts +1272 -279
- package/dist/host/agents/skills/orkestrel-harden/scripts/measure.ts +425 -0
- package/dist/host/agents/skills/orkestrel-harden/scripts/titles.ts +603 -98
- package/dist/host/agents/skills/orkestrel-journey/SKILL.md +75 -98
- package/dist/host/agents/skills/orkestrel-journey/references/captures.md +54 -17
- package/dist/host/agents/skills/orkestrel-journey/references/decide.md +1 -20
- package/dist/host/agents/skills/orkestrel-journey/references/layer.md +21 -31
- package/dist/host/agents/skills/orkestrel-journey/references/styles.md +1 -1
- package/dist/host/agents/skills/orkestrel-parallel/SKILL.md +28 -24
- package/dist/host/agents/skills/orkestrel-parallel/references/claude.md +15 -13
- package/dist/host/agents/skills/orkestrel-parallel/references/codex.md +1 -0
- package/dist/host/agents/skills/orkestrel-parallel/references/cursor.md +13 -13
- package/dist/host/agents/skills/orkestrel-parallel/scripts/cases.ts +389 -0
- package/dist/host/agents/skills/orkestrel-polish/SKILL.md +16 -20
- package/dist/host/agents/skills/orkestrel-polish/references/capture-harness.md +16 -26
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +12 -26
- package/dist/host/agents/skills/orkestrel-publish/agents/openai.yaml +2 -2
- package/dist/host/agents/skills/orkestrel-publish/references/adopt.md +23 -0
- package/dist/host/agents/skills/orkestrel-publish/references/release.md +4 -4
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +10 -9
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +20 -25
- package/dist/host/agents/skills/orkestrel-publish/scripts/compare.ts +348 -59
- package/dist/host/agents/skills/orkestrel-publish/scripts/pins.ts +202 -22
- package/dist/host/agents/skills/orkestrel-publish/scripts/swap.ts +1061 -191
- package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +812 -140
- package/dist/host/agents/skills/orkestrel-publish/scripts/window.ts +280 -38
- package/dist/host/agents/skills/orkestrel-scout/SKILL.md +3 -3
- package/dist/host/agents/skills/orkestrel-scout/scripts/map.ts +428 -70
- package/dist/host/agents/templates/brief.md +1 -1
- package/dist/host/agents/transports/claude-cli.md +3 -3
- package/dist/host/agents/transports/codex.md +2 -7
- package/dist/host/agents/transports/cursor.md +2 -3
- package/dist/host/claude/AGENTS.md +2 -2
- package/dist/host/claude/agents/analyst.md +3 -3
- package/dist/host/claude/agents/astra.md +3 -3
- package/dist/host/claude/agents/builder.md +1 -1
- package/dist/host/claude/agents/checker.md +1 -1
- package/dist/host/claude/agents/distiller.md +1 -1
- package/dist/host/claude/agents/grok.md +1 -1
- package/dist/host/claude/agents/opus.md +2 -2
- package/dist/host/claude/agents/orkestrel.md +57 -90
- package/dist/host/claude/agents/researcher.md +1 -1
- package/dist/host/claude/agents/reviewer.md +4 -0
- package/dist/host/claude/agents/scout.md +1 -1
- package/dist/host/claude/agents/verifier.md +1 -1
- package/dist/host/claude/rules/application.md +14 -21
- package/dist/host/claude/rules/architecture.md +34 -44
- package/dist/host/claude/rules/browser.md +3 -4
- package/dist/host/claude/rules/campaign.md +2 -2
- package/dist/host/claude/rules/documentation.md +25 -12
- package/dist/host/claude/rules/names.md +9 -4
- package/dist/host/claude/rules/patterns.md +6 -7
- package/dist/host/claude/rules/portability.md +1 -1
- package/dist/host/claude/rules/quality.md +4 -5
- package/dist/host/claude/rules/styles.md +2 -2
- package/dist/host/claude/rules/tests.md +57 -114
- package/dist/host/claude/rules/typescript.md +7 -9
- package/dist/host/claude/rules/workspace.md +21 -19
- package/dist/host/claude/rules/writing.md +2 -5
- package/dist/host/claude/skills/orkestrel-dispatch/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-harden/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-publish/SKILL.md +1 -1
- package/dist/host/claude/skills/orkestrel-scout/SKILL.md +1 -1
- package/dist/host/codex/agents/analyst.toml +9 -3
- package/dist/host/codex/agents/astra.toml +3 -4
- package/dist/host/codex/agents/builder.toml +1 -1
- package/dist/host/codex/agents/opus.toml +3 -4
- package/dist/host/codex/agents/orkestrel.toml +1 -1
- package/dist/host/codex/agents/researcher.toml +2 -2
- package/dist/host/codex/agents/verifier.toml +1 -1
- package/dist/host/configs/helpers.ts +21 -1
- package/dist/host/configs/policy.ts +299 -15
- package/dist/host/dotfiles/oxlintrc.json +137 -3
- package/dist/host/guides/agent.md +111 -134
- package/dist/host/guides/capture.md +801 -0
- package/dist/host/guides/probe.md +27 -8
- package/dist/host/guides/scaffold.md +96 -18
- package/dist/host/guides/study.md +534 -440
- package/dist/host/guides/test.md +111 -44
- package/dist/host/manifest.json +160 -240
- package/dist/host/tests/config.test.ts +971 -187
- package/dist/host/tests/policy.test.ts +127 -1
- package/dist/host/tests/setupPolicy.ts +893 -33
- package/dist/src/core/index.cjs +214 -86
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +122 -38
- package/dist/src/core/index.d.ts +122 -38
- package/dist/src/core/index.js +209 -85
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +20 -27
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.js +21 -28
- package/dist/src/server/index.js.map +1 -1
- package/package.json +11 -11
- package/dist/agents/skills/orkestrel-dispatch/scripts/helpers.js +0 -283
- package/dist/host/agents/skills/orkestrel-dispatch/references/bench.md +0 -25
- package/dist/host/agents/skills/orkestrel-dispatch/scripts/helpers.ts +0 -333
- package/dist/host/guides/supervisor.md +0 -4890
|
@@ -15,22 +15,49 @@
|
|
|
15
15
|
// acceptance line, stops at the first refusal and names the package to resume from, then confirms
|
|
16
16
|
// each accepted version against the registry. --confirm re-reads the registry for each name@version every 5
|
|
17
17
|
// seconds until it serves the version or the wait (default 120 seconds) ends. Exit 0 when the mode
|
|
18
|
-
// succeeded, 3 when it did not, 64 on usage
|
|
19
|
-
|
|
18
|
+
// succeeded, 3 when it did not, 64 on usage, including a flag the script does not read and the
|
|
19
|
+
// `--flag=value` form.
|
|
20
|
+
import type { SpawnSyncReturns } from 'node:child_process'
|
|
21
|
+
import { spawnSync } from 'node:child_process'
|
|
22
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from 'node:fs'
|
|
20
23
|
import { dirname, join, resolve } from 'node:path'
|
|
21
|
-
import {
|
|
22
|
-
parseJsonRecord,
|
|
23
|
-
readList,
|
|
24
|
-
readMissingFlags,
|
|
25
|
-
readOption,
|
|
26
|
-
readString,
|
|
27
|
-
runNpm,
|
|
28
|
-
} from '../../orkestrel-dispatch/scripts/helpers.ts'
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
const
|
|
25
|
+
/** Holds the milliseconds between two polls of the registry. */
|
|
26
|
+
export const POLL_MS = 5_000
|
|
32
27
|
|
|
33
|
-
|
|
28
|
+
/** Matches the acceptance line `npm publish` prints and captures the name and the version. */
|
|
29
|
+
export const ACCEPTED = /^\+ (\S+)@(\S+)\s*$/mu
|
|
30
|
+
|
|
31
|
+
/** Lists every flag the script reads, value flags and switches alike. */
|
|
32
|
+
export const FLAGS: readonly string[] = [
|
|
33
|
+
'--whoami',
|
|
34
|
+
'--login',
|
|
35
|
+
'--publish',
|
|
36
|
+
'--confirm',
|
|
37
|
+
'--wait',
|
|
38
|
+
'--otp',
|
|
39
|
+
'--json',
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
/** Holds the usage line the script prints when no mode or two modes were given. */
|
|
43
|
+
export const USAGE =
|
|
44
|
+
'usage: window.ts --whoami [--wait SECONDS] | --login [--wait SECONDS] | --publish DIR... --otp CODE [--json] | --confirm NAME@VERSION... [--wait SECONDS]'
|
|
45
|
+
|
|
46
|
+
/** Describes how to spawn npm on this host without a shell where the CLI entry is present. */
|
|
47
|
+
export interface NpmCommand {
|
|
48
|
+
readonly file: string
|
|
49
|
+
readonly prefix: readonly string[]
|
|
50
|
+
readonly shell: boolean
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Describes the name and version a package manifest declares. */
|
|
54
|
+
export interface ManifestName {
|
|
55
|
+
readonly name: string | undefined
|
|
56
|
+
readonly version: string | undefined
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Describes one package upload and what the registry did with it. */
|
|
60
|
+
export interface Upload {
|
|
34
61
|
readonly directory: string
|
|
35
62
|
readonly name: string | undefined
|
|
36
63
|
readonly version: string | undefined
|
|
@@ -41,36 +68,206 @@ interface Upload {
|
|
|
41
68
|
readonly journal: string
|
|
42
69
|
}
|
|
43
70
|
|
|
44
|
-
|
|
71
|
+
/** Describes the uploads a batch made and whether a refusal stopped it. */
|
|
72
|
+
export interface Published {
|
|
45
73
|
readonly uploads: readonly Upload[]
|
|
46
74
|
readonly stopped: boolean
|
|
47
75
|
}
|
|
48
76
|
|
|
49
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Reads the value that follows a flag.
|
|
79
|
+
*
|
|
80
|
+
* @remarks
|
|
81
|
+
* Reads `--flag value` pairs: the first occurrence of a flag wins, a following value that opens
|
|
82
|
+
* with `--` is a missing value, and the `--flag=value` form is not read.
|
|
83
|
+
*
|
|
84
|
+
* @param argv - The arguments after the script path.
|
|
85
|
+
* @param name - The flag, such as `--otp`.
|
|
86
|
+
* @returns The value after the flag, or undefined when the flag is absent, last, or followed by
|
|
87
|
+
* another flag.
|
|
88
|
+
*/
|
|
89
|
+
export function readOption(argv: readonly string[], name: string): string | undefined {
|
|
90
|
+
const index = argv.indexOf(name)
|
|
91
|
+
const value = index === -1 ? undefined : argv[index + 1]
|
|
92
|
+
return value === undefined || value.startsWith('--') ? undefined : value
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Names the value flags a caller gave with no value.
|
|
97
|
+
*
|
|
98
|
+
* @param argv - The arguments after the script path.
|
|
99
|
+
* @param names - The flags that take a value.
|
|
100
|
+
* @returns Each named flag that appears last or is followed by another flag, in argument order.
|
|
101
|
+
*/
|
|
102
|
+
export function readMissingFlags(
|
|
103
|
+
argv: readonly string[],
|
|
104
|
+
names: readonly string[],
|
|
105
|
+
): readonly string[] {
|
|
106
|
+
return names.filter((name) => argv.includes(name) && readOption(argv, name) === undefined)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Names the flags a caller gave that the script does not read.
|
|
111
|
+
*
|
|
112
|
+
* @remarks
|
|
113
|
+
* Reads the arguments before a bare `--`, which opens a command a script passes on. A `--flag=value`
|
|
114
|
+
* argument is unknown, because the script reads no such form.
|
|
115
|
+
*
|
|
116
|
+
* @param argv - The arguments after the script path.
|
|
117
|
+
* @param flags - Every flag the script reads, value flags and switches alike.
|
|
118
|
+
* @returns Each argument that opens with `--` and is not a read flag, in argument order.
|
|
119
|
+
*/
|
|
120
|
+
export function readUnknownFlags(
|
|
121
|
+
argv: readonly string[],
|
|
122
|
+
flags: readonly string[],
|
|
123
|
+
): readonly string[] {
|
|
124
|
+
const end = argv.indexOf('--')
|
|
125
|
+
return (end === -1 ? argv : argv.slice(0, end)).filter(
|
|
126
|
+
(argument) => argument.startsWith('--') && !flags.includes(argument),
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Reads the values that follow a flag up to the next flag.
|
|
132
|
+
*
|
|
133
|
+
* @param argv - The arguments after the script path.
|
|
134
|
+
* @param name - The flag, such as `--publish`.
|
|
135
|
+
* @returns The values between the flag and the next `--` argument, empty when the flag is absent.
|
|
136
|
+
*/
|
|
137
|
+
export function readList(argv: readonly string[], name: string): readonly string[] {
|
|
138
|
+
const index = argv.indexOf(name)
|
|
139
|
+
if (index === -1) return []
|
|
140
|
+
const rest = argv.slice(index + 1)
|
|
141
|
+
const end = rest.findIndex((argument) => argument.startsWith('--'))
|
|
142
|
+
return end === -1 ? rest : rest.slice(0, end)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Parses a whole text as one JSON object.
|
|
147
|
+
*
|
|
148
|
+
* @param text - A JSON document, formatted or not, such as a manifest.
|
|
149
|
+
* @returns The parsed object, or undefined when the text is not a JSON object.
|
|
150
|
+
*/
|
|
151
|
+
export function parseJsonRecord(text: string): Record<string, unknown> | undefined {
|
|
152
|
+
try {
|
|
153
|
+
const parsed: unknown = JSON.parse(text)
|
|
154
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
155
|
+
return Object.fromEntries(Object.entries(parsed))
|
|
156
|
+
}
|
|
157
|
+
} catch {}
|
|
158
|
+
return undefined
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Reads a string member of a record.
|
|
163
|
+
*
|
|
164
|
+
* @param record - The record, or undefined.
|
|
165
|
+
* @param key - The member name.
|
|
166
|
+
* @returns The string, or undefined when the member is absent or not a string.
|
|
167
|
+
*/
|
|
168
|
+
export function readString(
|
|
169
|
+
record: Record<string, unknown> | undefined,
|
|
170
|
+
key: string,
|
|
171
|
+
): string | undefined {
|
|
172
|
+
const value = record?.[key]
|
|
173
|
+
return typeof value === 'string' ? value : undefined
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Resolves the npm command for this host.
|
|
178
|
+
*
|
|
179
|
+
* @remarks
|
|
180
|
+
* The `npm-cli.js` entry beside the running Node binary spawns without a shell on every host; the
|
|
181
|
+
* `npm` shim on Windows is a `.cmd` file that needs one, so that path is the fallback alone.
|
|
182
|
+
*
|
|
183
|
+
* @returns The file to spawn, the arguments that precede npm's own, and whether a shell is needed.
|
|
184
|
+
*/
|
|
185
|
+
export function resolveNpm(): NpmCommand {
|
|
186
|
+
const cli = join(dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npm-cli.js')
|
|
187
|
+
if (existsSync(cli)) return { file: process.execPath, prefix: [cli], shell: false }
|
|
188
|
+
return { file: 'npm', prefix: [], shell: process.platform === 'win32' }
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Runs npm with the given arguments and returns the finished child.
|
|
193
|
+
*
|
|
194
|
+
* @param args - The npm arguments, such as `['whoami']`.
|
|
195
|
+
* @param cwd - The working directory. Default: the current directory.
|
|
196
|
+
* @returns The spawn result with `utf8` stdout and stderr.
|
|
197
|
+
*/
|
|
198
|
+
export function runNpm(args: readonly string[], cwd?: string): SpawnSyncReturns<string> {
|
|
199
|
+
const npm = resolveNpm()
|
|
200
|
+
return spawnSync(npm.file, [...npm.prefix, ...args], {
|
|
201
|
+
encoding: 'utf8',
|
|
202
|
+
windowsHide: true,
|
|
203
|
+
shell: npm.shell,
|
|
204
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
205
|
+
...(cwd === undefined ? {} : { cwd }),
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Waits for a number of milliseconds.
|
|
211
|
+
*
|
|
212
|
+
* @param ms - The delay.
|
|
213
|
+
* @returns A promise that settles after the delay.
|
|
214
|
+
*/
|
|
215
|
+
export function waitFor(ms: number): Promise<void> {
|
|
50
216
|
return new Promise((settle) => {
|
|
51
217
|
setTimeout(settle, ms)
|
|
52
218
|
})
|
|
53
219
|
}
|
|
54
220
|
|
|
55
|
-
|
|
221
|
+
/**
|
|
222
|
+
* Reads the account `npm whoami` names once.
|
|
223
|
+
*
|
|
224
|
+
* @returns The user name, or undefined when npm exited nonzero or printed nothing.
|
|
225
|
+
*/
|
|
226
|
+
export function readWhoami(): string | undefined {
|
|
56
227
|
const result = runNpm(['whoami'])
|
|
57
228
|
const user = result.stdout.trim()
|
|
58
229
|
return result.status === 0 && user !== '' ? user : undefined
|
|
59
230
|
}
|
|
60
231
|
|
|
61
|
-
|
|
232
|
+
/**
|
|
233
|
+
* Polls `npm whoami` until it answers or the wait ends.
|
|
234
|
+
*
|
|
235
|
+
* @param waitSeconds - How long to keep polling; 0 reads once.
|
|
236
|
+
* @param started - The millisecond the polling began. Default: now.
|
|
237
|
+
* @returns The user name, or undefined when none answered within the wait.
|
|
238
|
+
*/
|
|
239
|
+
export async function pollWhoami(
|
|
240
|
+
waitSeconds: number,
|
|
241
|
+
started = Date.now(),
|
|
242
|
+
): Promise<string | undefined> {
|
|
62
243
|
const user = readWhoami()
|
|
63
244
|
if (user !== undefined || Date.now() - started >= waitSeconds * 1000) return user
|
|
64
245
|
await waitFor(POLL_MS)
|
|
65
246
|
return pollWhoami(waitSeconds, started)
|
|
66
247
|
}
|
|
67
248
|
|
|
68
|
-
|
|
249
|
+
/**
|
|
250
|
+
* Checks whether the registry serves one version of a package.
|
|
251
|
+
*
|
|
252
|
+
* @param name - The package name.
|
|
253
|
+
* @param version - The version.
|
|
254
|
+
* @returns True if `npm view` reads exactly that version; false otherwise.
|
|
255
|
+
*/
|
|
256
|
+
export function readServed(name: string, version: string): boolean {
|
|
69
257
|
const result = runNpm(['view', `${name}@${version}`, 'version', '--json'])
|
|
70
258
|
return result.status === 0 && result.stdout.replace(/["\s]/gu, '') === version
|
|
71
259
|
}
|
|
72
260
|
|
|
73
|
-
|
|
261
|
+
/**
|
|
262
|
+
* Polls the registry until it serves one version or the wait ends.
|
|
263
|
+
*
|
|
264
|
+
* @param name - The package name.
|
|
265
|
+
* @param version - The version.
|
|
266
|
+
* @param waitSeconds - How long to keep polling; 0 reads once.
|
|
267
|
+
* @param started - The millisecond the polling began. Default: now.
|
|
268
|
+
* @returns True if the registry served the version within the wait; false otherwise.
|
|
269
|
+
*/
|
|
270
|
+
export async function confirmServed(
|
|
74
271
|
name: string,
|
|
75
272
|
version: string,
|
|
76
273
|
waitSeconds: number,
|
|
@@ -82,20 +279,35 @@ async function confirmServed(
|
|
|
82
279
|
return confirmServed(name, version, waitSeconds, started)
|
|
83
280
|
}
|
|
84
281
|
|
|
85
|
-
|
|
282
|
+
/**
|
|
283
|
+
* Finds the nearest directory at or above one that holds a `.git` entry.
|
|
284
|
+
*
|
|
285
|
+
* @param directory - The directory to start from.
|
|
286
|
+
* @returns The nearest directory with a `.git` entry, or the filesystem root when none has one.
|
|
287
|
+
*/
|
|
288
|
+
export function findGitRoot(directory: string): string {
|
|
86
289
|
return existsSync(join(directory, '.git')) || dirname(directory) === directory
|
|
87
290
|
? directory
|
|
88
291
|
: findGitRoot(dirname(directory))
|
|
89
292
|
}
|
|
90
293
|
|
|
91
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Reads the error code npm printed.
|
|
296
|
+
*
|
|
297
|
+
* @param text - npm's standard error.
|
|
298
|
+
* @returns The first `E` code in the text, such as `EOTP` or `E401`, or undefined when none appears.
|
|
299
|
+
*/
|
|
300
|
+
export function readErrorCode(text: string): string | undefined {
|
|
92
301
|
return text.match(/\b(E[A-Z0-9]{3,}|EOTP|E401|E403|E404)\b/u)?.[1]
|
|
93
302
|
}
|
|
94
303
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Reads the name and version a directory's package manifest declares.
|
|
306
|
+
*
|
|
307
|
+
* @param directory - The directory that holds `package.json`.
|
|
308
|
+
* @returns The name and version, each undefined when the manifest is absent, unreadable, or lacks it.
|
|
309
|
+
*/
|
|
310
|
+
export function readManifestName(directory: string): ManifestName {
|
|
99
311
|
const path = join(directory, 'package.json')
|
|
100
312
|
if (!existsSync(path)) return { name: undefined, version: undefined }
|
|
101
313
|
try {
|
|
@@ -106,7 +318,15 @@ function readManifestName(directory: string): {
|
|
|
106
318
|
}
|
|
107
319
|
}
|
|
108
320
|
|
|
109
|
-
|
|
321
|
+
/**
|
|
322
|
+
* Publishes one package directory and journals the upload.
|
|
323
|
+
*
|
|
324
|
+
* @param directory - The package directory.
|
|
325
|
+
* @param otp - The account's one-time code.
|
|
326
|
+
* @returns The upload: accepted when npm exited 0 and printed the acceptance line, else refused with
|
|
327
|
+
* the error code npm named.
|
|
328
|
+
*/
|
|
329
|
+
export function publishPackage(directory: string, otp: string): Upload {
|
|
110
330
|
const manifest = readManifestName(directory)
|
|
111
331
|
const journal = `tmp/units/publish-${(manifest.name ?? directory).replace(/[^A-Za-z0-9.-]+/gu, '-')}.log`
|
|
112
332
|
// The refusal code must survive an inherited silent npm log level.
|
|
@@ -139,7 +359,16 @@ function publishPackage(directory: string, otp: string): Upload {
|
|
|
139
359
|
return upload
|
|
140
360
|
}
|
|
141
361
|
|
|
142
|
-
|
|
362
|
+
/**
|
|
363
|
+
* Publishes a batch back to back and confirms each accepted version.
|
|
364
|
+
*
|
|
365
|
+
* @param directories - The package directories, in publish order.
|
|
366
|
+
* @param otp - The account's one-time code.
|
|
367
|
+
* @param waitSeconds - How long to wait for the registry to serve each accepted version.
|
|
368
|
+
* @returns One upload per directory published, ending at the first refusal; a directory after it is
|
|
369
|
+
* not published.
|
|
370
|
+
*/
|
|
371
|
+
export async function publishAll(
|
|
143
372
|
directories: readonly string[],
|
|
144
373
|
otp: string,
|
|
145
374
|
waitSeconds: number,
|
|
@@ -168,7 +397,20 @@ async function publishAll(
|
|
|
168
397
|
return confirmed
|
|
169
398
|
}
|
|
170
399
|
|
|
171
|
-
|
|
400
|
+
/**
|
|
401
|
+
* Runs the mode the arguments name.
|
|
402
|
+
*
|
|
403
|
+
* @param argv - The arguments after the script path.
|
|
404
|
+
* @returns The exit code: 0 when the mode succeeded, 3 when it did not, 64 on usage.
|
|
405
|
+
*/
|
|
406
|
+
export async function main(argv: readonly string[]): Promise<number> {
|
|
407
|
+
const unknown = readUnknownFlags(argv, FLAGS)
|
|
408
|
+
if (unknown.length > 0) {
|
|
409
|
+
console.error(
|
|
410
|
+
`window: unknown flag ${unknown.join(', ')}; give each flag and its value as separate arguments\n${USAGE}`,
|
|
411
|
+
)
|
|
412
|
+
return 64
|
|
413
|
+
}
|
|
172
414
|
const missing = readMissingFlags(argv, ['--wait', '--otp'])
|
|
173
415
|
if (missing.length > 0) {
|
|
174
416
|
console.error(`window: ${missing.join(', ')} given with no value`)
|
|
@@ -265,23 +507,23 @@ async function main(argv: readonly string[]): Promise<number> {
|
|
|
265
507
|
console.error('usage: window.ts --confirm NAME@VERSION... [--wait SECONDS]')
|
|
266
508
|
return 64
|
|
267
509
|
}
|
|
268
|
-
const
|
|
510
|
+
const results: Array<{ readonly target: string; readonly served: boolean }> = []
|
|
269
511
|
for (const target of targets) {
|
|
270
512
|
const at = target.lastIndexOf('@')
|
|
271
|
-
|
|
513
|
+
results.push({
|
|
272
514
|
target,
|
|
273
515
|
served: await confirmServed(target.slice(0, at), target.slice(at + 1), wait),
|
|
274
516
|
})
|
|
275
517
|
}
|
|
276
|
-
console.log(JSON.stringify({ mode: 'confirm',
|
|
277
|
-
return
|
|
518
|
+
console.log(JSON.stringify({ mode: 'confirm', results }))
|
|
519
|
+
return results.every((result) => result.served) ? 0 : 3
|
|
278
520
|
}
|
|
279
|
-
console.error(
|
|
280
|
-
'usage: window.ts --whoami [--wait SECONDS] | --login [--wait SECONDS] | --publish DIR... --otp CODE [--json] | --confirm NAME@VERSION... [--wait SECONDS]',
|
|
281
|
-
)
|
|
521
|
+
console.error(USAGE)
|
|
282
522
|
return 64
|
|
283
523
|
}
|
|
284
524
|
|
|
285
|
-
|
|
286
|
-
process.
|
|
287
|
-
|
|
525
|
+
if (process.argv[1] !== undefined && realpathSync(process.argv[1]) === import.meta.filename) {
|
|
526
|
+
main(process.argv.slice(2)).then((code) => {
|
|
527
|
+
process.exitCode = code
|
|
528
|
+
})
|
|
529
|
+
}
|
|
@@ -10,9 +10,9 @@ A map is mechanical; reading is not. Run the map first, hand it to the reader, a
|
|
|
10
10
|
|
|
11
11
|
## Scripts
|
|
12
12
|
|
|
13
|
-
| Script | Does
|
|
14
|
-
| ---------------- |
|
|
15
|
-
| `scripts/map.ts` | `--tree PATH...` files with line counts and sizes; `--headings PATH...` Markdown headings with lines; `--frontmatter PATH...` every key of a frontmatter block, a TOML file, or a YAML file with its whole value, nested keys dotted (`interface.default_prompt`); `--exports PATH...` `export` lines in TypeScript files (a text reading); `--census TERM...` every line carrying a term (a term that opens with `--` is refused as a missing value, so drop a custom property's leading dashes); `--refs PATH` every line naming a path or its basename; `--anchors PATH...` every `§ Heading` reference whose heading its target lacks. `--paths a,b` narrows a census or refs walk; `--ignore-case`; `--json`; `--out FILE` writes the map instead of printing it. Walks skip `node_modules`, `.git`, `dist`, `tmp`, `.orkestrel`, `.idea`, and `host.json`. |
|
|
13
|
+
| Script | Does |
|
|
14
|
+
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| `scripts/map.ts` | `--tree PATH...` files with line counts and sizes; `--headings PATH...` Markdown headings with lines, outside fenced blocks of backticks or tildes; `--frontmatter PATH...` every key of a frontmatter block, a TOML file, or a YAML file with its whole value, nested keys dotted (`interface.default_prompt`); `--exports PATH...` `export` lines in TypeScript files (a text reading); `--census TERM...` every line carrying a term (a term that opens with `--` is refused as a missing value, so drop a custom property's leading dashes); `--refs PATH` every line naming a path or its basename; `--anchors PATH...` every `§ Heading` reference whose heading its target lacks. `--paths a,b` narrows a census or refs walk; `--ignore-case`; `--json`; `--out FILE` writes the map instead of printing it. Walks skip `node_modules`, `.git`, `dist`, `tmp`, `.orkestrel`, `.idea`, and `host.json`. |
|
|
16
16
|
|
|
17
17
|
## Map
|
|
18
18
|
|