@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
|
@@ -9,43 +9,174 @@
|
|
|
9
9
|
// launch.ts wrote (`exit`, `capped`, `durationMs`) and the journal's `bytes`, `ageMs`, and last
|
|
10
10
|
// event, which is the liveness reading for a run still going. The answer is written to --out when
|
|
11
11
|
// given, and a journal with no session or answer exits 3 so a driver cannot pass off an empty lane.
|
|
12
|
-
|
|
12
|
+
// Name one mode per run; the script refuses a flag it does not read, the `--flag=value` form
|
|
13
|
+
// included. Exit 0 when the lane answered, 3 when it carries no session or answer, 64 on usage.
|
|
14
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from 'node:fs'
|
|
13
15
|
import { dirname } from 'node:path'
|
|
14
|
-
import { readMissingFlags, readNumber, readOption, readString } from './helpers.ts'
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
/** Lists the flags that each select one journal reader. */
|
|
18
|
+
export const MODE_FLAGS: readonly string[] = ['--cursor', '--claude', '--codex']
|
|
19
|
+
|
|
20
|
+
/** Lists the flags that take a value. */
|
|
21
|
+
export const VALUE_FLAGS: readonly string[] = [...MODE_FLAGS, '--out']
|
|
22
|
+
|
|
23
|
+
/** Lists every flag the script reads, value flags and switches alike. */
|
|
24
|
+
export const FLAGS: readonly string[] = VALUE_FLAGS
|
|
25
|
+
|
|
26
|
+
/** Holds the usage line printed when a call names no journal or two modes. */
|
|
27
|
+
export const USAGE =
|
|
28
|
+
'usage: result.ts (--cursor JOURNAL | --claude JOURNAL | --codex JOURNAL) [--out PATH]; name one mode'
|
|
29
|
+
|
|
30
|
+
/** Describes what a journal's events say: the session, the answer, and the run's duration. */
|
|
31
|
+
export interface SessionResult {
|
|
17
32
|
readonly session: string | undefined
|
|
18
33
|
readonly answer: string | undefined
|
|
19
34
|
readonly durationMs: number | undefined
|
|
20
35
|
}
|
|
21
36
|
|
|
22
|
-
|
|
37
|
+
/** Describes what the sibling errors file says about the run that wrote the journal. */
|
|
38
|
+
export interface Errors {
|
|
23
39
|
readonly exit: number | undefined
|
|
24
40
|
readonly capped: boolean | undefined
|
|
25
41
|
readonly durationMs: number | undefined
|
|
26
42
|
}
|
|
27
43
|
|
|
28
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Reads the value that follows a flag.
|
|
46
|
+
*
|
|
47
|
+
* @remarks
|
|
48
|
+
* The first occurrence of a flag wins, a following value that opens with `--` is a missing value,
|
|
49
|
+
* and the `--flag=value` form is not read.
|
|
50
|
+
*
|
|
51
|
+
* @param argv - The arguments after the script path.
|
|
52
|
+
* @param name - The flag, such as `--out`.
|
|
53
|
+
* @returns The value after the flag, or undefined when the flag is absent, last, or followed by
|
|
54
|
+
* another flag.
|
|
55
|
+
*/
|
|
56
|
+
export function readOption(argv: readonly string[], name: string): string | undefined {
|
|
57
|
+
const index = argv.indexOf(name)
|
|
58
|
+
const value = index === -1 ? undefined : argv[index + 1]
|
|
59
|
+
return value === undefined || value.startsWith('--') ? undefined : value
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Names the value flags a caller gave with no value.
|
|
64
|
+
*
|
|
65
|
+
* @param argv - The arguments after the script path.
|
|
66
|
+
* @param names - The flags that take a value.
|
|
67
|
+
* @returns Each named flag that appears last or is followed by another flag, in argument order.
|
|
68
|
+
*/
|
|
69
|
+
export function readMissingFlags(
|
|
70
|
+
argv: readonly string[],
|
|
71
|
+
names: readonly string[],
|
|
72
|
+
): readonly string[] {
|
|
73
|
+
return names.filter((name) => argv.includes(name) && readOption(argv, name) === undefined)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Names the flags a caller gave that the script does not read.
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* A `--flag=value` argument is unknown, because the script reads no such form. A bare `--` ends the
|
|
81
|
+
* scan.
|
|
82
|
+
*
|
|
83
|
+
* @param argv - The arguments after the script path.
|
|
84
|
+
* @param flags - Every flag the script reads, value flags and switches alike.
|
|
85
|
+
* @returns Each argument that opens with `--` and is not a read flag, in argument order.
|
|
86
|
+
*/
|
|
87
|
+
export function readUnknownFlags(
|
|
88
|
+
argv: readonly string[],
|
|
89
|
+
flags: readonly string[],
|
|
90
|
+
): readonly string[] {
|
|
91
|
+
const end = argv.indexOf('--')
|
|
92
|
+
return (end === -1 ? argv : argv.slice(0, end)).filter(
|
|
93
|
+
(argument) => argument.startsWith('--') && !flags.includes(argument),
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Reads the last non-empty line of a text as a JSON object.
|
|
99
|
+
*
|
|
100
|
+
* @param text - Text whose last line is JSON, such as one journal line.
|
|
101
|
+
* @returns The parsed object, or undefined when the last line is not a JSON object.
|
|
102
|
+
*/
|
|
103
|
+
export function parseJsonLine(text: string): Record<string, unknown> | undefined {
|
|
104
|
+
const line = text
|
|
105
|
+
.split(/\r\n|\n/)
|
|
106
|
+
.filter((candidate) => candidate.trim() !== '')
|
|
107
|
+
.at(-1)
|
|
108
|
+
if (line === undefined) return undefined
|
|
109
|
+
try {
|
|
110
|
+
const parsed: unknown = JSON.parse(line)
|
|
111
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
112
|
+
return Object.fromEntries(Object.entries(parsed))
|
|
113
|
+
}
|
|
114
|
+
} catch {}
|
|
115
|
+
return undefined
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Reads a string member of a record.
|
|
120
|
+
*
|
|
121
|
+
* @param record - The record, or undefined.
|
|
122
|
+
* @param key - The member name.
|
|
123
|
+
* @returns The string, or undefined when the member is absent or not a string.
|
|
124
|
+
*/
|
|
125
|
+
export function readString(
|
|
126
|
+
record: Record<string, unknown> | undefined,
|
|
127
|
+
key: string,
|
|
128
|
+
): string | undefined {
|
|
129
|
+
const value = record?.[key]
|
|
130
|
+
return typeof value === 'string' ? value : undefined
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Reads a finite number member of a record.
|
|
135
|
+
*
|
|
136
|
+
* @param record - The record, or undefined.
|
|
137
|
+
* @param key - The member name.
|
|
138
|
+
* @returns The number, or undefined when the member is absent, not a number, or not finite.
|
|
139
|
+
*/
|
|
140
|
+
export function readNumber(
|
|
141
|
+
record: Record<string, unknown> | undefined,
|
|
142
|
+
key: string,
|
|
143
|
+
): number | undefined {
|
|
144
|
+
const value = record?.[key]
|
|
145
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Reads every JSON object line of a journal.
|
|
150
|
+
*
|
|
151
|
+
* @param path - The journal file.
|
|
152
|
+
* @returns Each line that parses as a JSON object, in order; a blank or malformed line is skipped.
|
|
153
|
+
*/
|
|
154
|
+
export function readEvents(path: string): ReadonlyArray<Record<string, unknown>> {
|
|
29
155
|
return readFileSync(path, 'utf8')
|
|
30
156
|
.split(/\r\n|\n/)
|
|
31
157
|
.flatMap((line) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const parsed: unknown = JSON.parse(line)
|
|
35
|
-
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)
|
|
36
|
-
? [Object.fromEntries(Object.entries(parsed))]
|
|
37
|
-
: []
|
|
38
|
-
} catch {
|
|
39
|
-
return []
|
|
40
|
-
}
|
|
158
|
+
const event = parseJsonLine(line)
|
|
159
|
+
return event === undefined ? [] : [event]
|
|
41
160
|
})
|
|
42
161
|
}
|
|
43
162
|
|
|
44
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Reads an answer text as present only when it carries something besides whitespace.
|
|
165
|
+
*
|
|
166
|
+
* @param text - The answer text, or undefined.
|
|
167
|
+
* @returns The text unchanged, or undefined when it is absent or blank.
|
|
168
|
+
*/
|
|
169
|
+
export function readAnswer(text: string | undefined): string | undefined {
|
|
45
170
|
return text === undefined || text.trim() === '' ? undefined : text
|
|
46
171
|
}
|
|
47
172
|
|
|
48
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Reads a Cursor or Claude stream journal's events.
|
|
175
|
+
*
|
|
176
|
+
* @param events - The journal's events.
|
|
177
|
+
* @returns The session from the `init` event and the answer and duration from the `result` event.
|
|
178
|
+
*/
|
|
179
|
+
export function readStream(events: ReadonlyArray<Record<string, unknown>>): SessionResult {
|
|
49
180
|
const init = events.find((event) => event.type === 'system' && event.subtype === 'init')
|
|
50
181
|
const result = events.find((event) => event.type === 'result')
|
|
51
182
|
return {
|
|
@@ -55,7 +186,17 @@ function readStream(events: ReadonlyArray<Record<string, unknown>>): Reading {
|
|
|
55
186
|
}
|
|
56
187
|
}
|
|
57
188
|
|
|
58
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Reads a Codex journal's events and its sibling last-message file.
|
|
191
|
+
*
|
|
192
|
+
* @param path - The journal path; the answer sits beside it in `<name>-last.md`.
|
|
193
|
+
* @param events - The journal's events.
|
|
194
|
+
* @returns The thread id from the `thread.started` event and the answer from the last-message file.
|
|
195
|
+
*/
|
|
196
|
+
export function readCodex(
|
|
197
|
+
path: string,
|
|
198
|
+
events: ReadonlyArray<Record<string, unknown>>,
|
|
199
|
+
): SessionResult {
|
|
59
200
|
const started = events.find((event) => event.type === 'thread.started')
|
|
60
201
|
const last = path.replace(/\.jsonl$/u, '-last.md')
|
|
61
202
|
return {
|
|
@@ -65,7 +206,14 @@ function readCodex(path: string, events: ReadonlyArray<Record<string, unknown>>)
|
|
|
65
206
|
}
|
|
66
207
|
}
|
|
67
208
|
|
|
68
|
-
|
|
209
|
+
/**
|
|
210
|
+
* Reads the exit trailer launch.ts wrote to the errors file beside a journal.
|
|
211
|
+
*
|
|
212
|
+
* @param path - The journal path; the trailer sits beside it in `<name>.err`.
|
|
213
|
+
* @returns The exit code, whether the run was capped, and its duration; each is undefined when the
|
|
214
|
+
* file is absent or carries no trailer.
|
|
215
|
+
*/
|
|
216
|
+
export function readErrors(path: string): Errors {
|
|
69
217
|
const errors = path.replace(/\.jsonl$/u, '.err')
|
|
70
218
|
if (!existsSync(errors)) return { exit: undefined, capped: undefined, durationMs: undefined }
|
|
71
219
|
const match = readFileSync(errors, 'utf8').match(
|
|
@@ -80,52 +228,69 @@ function readErrors(path: string): Errors {
|
|
|
80
228
|
}
|
|
81
229
|
}
|
|
82
230
|
|
|
83
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Describes an event by its type and subtype.
|
|
233
|
+
*
|
|
234
|
+
* @param event - The event, or undefined.
|
|
235
|
+
* @returns `type` or `type/subtype`, or undefined when there is no event.
|
|
236
|
+
*/
|
|
237
|
+
export function describeEvent(event: Record<string, unknown> | undefined): string | undefined {
|
|
84
238
|
if (event === undefined) return undefined
|
|
85
239
|
const type = readString(event, 'type')
|
|
86
240
|
const subtype = readString(event, 'subtype')
|
|
87
241
|
return subtype === undefined ? type : `${type}/${subtype}`
|
|
88
242
|
}
|
|
89
243
|
|
|
90
|
-
|
|
91
|
-
|
|
244
|
+
/**
|
|
245
|
+
* Runs the script on its arguments.
|
|
246
|
+
*
|
|
247
|
+
* @param argv - The arguments after the script path.
|
|
248
|
+
* @returns The exit code: 0 when the lane answered, 3 when it carries no session or answer, 64 on usage.
|
|
249
|
+
*/
|
|
250
|
+
export function main(argv: readonly string[]): number {
|
|
251
|
+
const unknown = readUnknownFlags(argv, FLAGS)
|
|
252
|
+
if (unknown.length > 0) {
|
|
253
|
+
console.error(`result: ${unknown.join(', ')} is not a flag this script reads; ${USAGE}`)
|
|
254
|
+
return 64
|
|
255
|
+
}
|
|
256
|
+
const missing = readMissingFlags(argv, VALUE_FLAGS)
|
|
92
257
|
if (missing.length > 0) {
|
|
93
258
|
console.error(`result: ${missing.join(', ')} given with no value`)
|
|
94
259
|
return 64
|
|
95
260
|
}
|
|
96
|
-
const modes =
|
|
261
|
+
const modes = MODE_FLAGS.filter((flag) => argv.includes(flag))
|
|
97
262
|
const mode = modes[0]
|
|
98
263
|
const path = mode === undefined ? undefined : readOption(argv, mode)
|
|
99
264
|
const out = readOption(argv, '--out')
|
|
100
265
|
if (modes.length !== 1 || mode === undefined || path === undefined || !existsSync(path)) {
|
|
101
|
-
console.error(
|
|
102
|
-
'usage: result.ts (--cursor JOURNAL | --claude JOURNAL | --codex JOURNAL) [--out PATH]; name one mode',
|
|
103
|
-
)
|
|
266
|
+
console.error(USAGE)
|
|
104
267
|
return 64
|
|
105
268
|
}
|
|
106
269
|
const events = readEvents(path)
|
|
107
|
-
const
|
|
270
|
+
const result = mode === '--codex' ? readCodex(path, events) : readStream(events)
|
|
108
271
|
const errors = readErrors(path)
|
|
109
272
|
const stat = statSync(path)
|
|
110
|
-
if (
|
|
273
|
+
if (result.answer !== undefined && out !== undefined) {
|
|
111
274
|
mkdirSync(dirname(out), { recursive: true })
|
|
112
|
-
writeFileSync(out,
|
|
275
|
+
writeFileSync(out, result.answer)
|
|
113
276
|
}
|
|
114
277
|
console.log(
|
|
115
278
|
JSON.stringify({
|
|
116
279
|
journal: path,
|
|
117
|
-
session:
|
|
118
|
-
durationMs:
|
|
280
|
+
session: result.session,
|
|
281
|
+
durationMs: result.durationMs ?? errors.durationMs,
|
|
119
282
|
exit: errors.exit,
|
|
120
283
|
capped: errors.capped,
|
|
121
284
|
bytes: stat.size,
|
|
122
285
|
ageMs: Math.max(0, Math.round(Date.now() - stat.mtimeMs)),
|
|
123
286
|
lastEvent: describeEvent(events.at(-1)),
|
|
124
|
-
answerLength:
|
|
125
|
-
out:
|
|
287
|
+
answerLength: result.answer?.length ?? 0,
|
|
288
|
+
out: result.answer === undefined ? undefined : out,
|
|
126
289
|
}),
|
|
127
290
|
)
|
|
128
|
-
return
|
|
291
|
+
return result.session === undefined || result.answer === undefined ? 3 : 0
|
|
129
292
|
}
|
|
130
293
|
|
|
131
|
-
process.
|
|
294
|
+
if (process.argv[1] !== undefined && realpathSync(process.argv[1]) === import.meta.filename) {
|
|
295
|
+
process.exitCode = main(process.argv.slice(2))
|
|
296
|
+
}
|