@nonameolsson/nightjar 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +341 -2
- package/dist/adapter-module.d.ts +18 -0
- package/dist/adapter-module.js +83 -0
- package/dist/adapter-module.js.map +1 -0
- package/dist/adapters.d.ts +15 -0
- package/dist/adapters.js +160 -0
- package/dist/adapters.js.map +1 -0
- package/dist/args.d.ts +12 -0
- package/dist/args.js +79 -0
- package/dist/args.js.map +1 -0
- package/dist/ask.d.ts +6 -0
- package/dist/ask.js +27 -0
- package/dist/ask.js.map +1 -0
- package/dist/azure-devops/api.d.ts +34 -0
- package/dist/azure-devops/api.js +98 -0
- package/dist/azure-devops/api.js.map +1 -0
- package/dist/azure-devops/code-host.d.ts +36 -0
- package/dist/azure-devops/code-host.js +185 -0
- package/dist/azure-devops/code-host.js.map +1 -0
- package/dist/azure-devops/fake-azure-devops.d.ts +90 -0
- package/dist/azure-devops/fake-azure-devops.js +728 -0
- package/dist/azure-devops/fake-azure-devops.js.map +1 -0
- package/dist/azure-devops/index.d.ts +8 -0
- package/dist/azure-devops/index.js +11 -0
- package/dist/azure-devops/index.js.map +1 -0
- package/dist/azure-devops/sign-in.d.ts +11 -0
- package/dist/azure-devops/sign-in.js +68 -0
- package/dist/azure-devops/sign-in.js.map +1 -0
- package/dist/azure-devops/text.d.ts +1 -0
- package/dist/azure-devops/text.js +41 -0
- package/dist/azure-devops/text.js.map +1 -0
- package/dist/azure-devops/tracker.d.ts +44 -0
- package/dist/azure-devops/tracker.js +333 -0
- package/dist/azure-devops/tracker.js.map +1 -0
- package/dist/build.d.ts +72 -0
- package/dist/build.js +442 -0
- package/dist/build.js.map +1 -0
- package/dist/check.d.ts +8 -0
- package/dist/check.js +25 -0
- package/dist/check.js.map +1 -0
- package/dist/checks.d.ts +38 -0
- package/dist/checks.js +179 -0
- package/dist/checks.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +11 -0
- package/dist/cli.js.map +1 -0
- package/dist/code-host.d.ts +19 -0
- package/dist/code-host.js +2 -0
- package/dist/code-host.js.map +1 -0
- package/dist/config.d.ts +65 -0
- package/dist/config.js +215 -0
- package/dist/config.js.map +1 -0
- package/dist/contract/case.d.ts +4 -0
- package/dist/contract/case.js +2 -0
- package/dist/contract/case.js.map +1 -0
- package/dist/contract/code-host.d.ts +24 -0
- package/dist/contract/code-host.js +108 -0
- package/dist/contract/code-host.js.map +1 -0
- package/dist/contract/command.d.ts +2 -0
- package/dist/contract/command.js +36 -0
- package/dist/contract/command.js.map +1 -0
- package/dist/contract/feature-writer.d.ts +3 -0
- package/dist/contract/feature-writer.js +101 -0
- package/dist/contract/feature-writer.js.map +1 -0
- package/dist/contract/run.d.ts +18 -0
- package/dist/contract/run.js +89 -0
- package/dist/contract/run.js.map +1 -0
- package/dist/contract/tracker.d.ts +30 -0
- package/dist/contract/tracker.js +250 -0
- package/dist/contract/tracker.js.map +1 -0
- package/dist/create.d.ts +9 -0
- package/dist/create.js +112 -0
- package/dist/create.js.map +1 -0
- package/dist/doctor.d.ts +4 -0
- package/dist/doctor.js +37 -0
- package/dist/doctor.js.map +1 -0
- package/dist/fakes/code-host.d.ts +21 -0
- package/dist/fakes/code-host.js +42 -0
- package/dist/fakes/code-host.js.map +1 -0
- package/dist/fakes/harness.d.ts +7 -0
- package/dist/fakes/harness.js +68 -0
- package/dist/fakes/harness.js.map +1 -0
- package/dist/fakes/machine.d.ts +10 -0
- package/dist/fakes/machine.js +94 -0
- package/dist/fakes/machine.js.map +1 -0
- package/dist/fakes/tracker.d.ts +40 -0
- package/dist/fakes/tracker.js +116 -0
- package/dist/fakes/tracker.js.map +1 -0
- package/dist/feature-file.d.ts +12 -0
- package/dist/feature-file.js +84 -0
- package/dist/feature-file.js.map +1 -0
- package/dist/git.d.ts +9 -0
- package/dist/git.js +12 -0
- package/dist/git.js.map +1 -0
- package/dist/github/api.d.ts +37 -0
- package/dist/github/api.js +66 -0
- package/dist/github/api.js.map +1 -0
- package/dist/github/code-host.d.ts +19 -0
- package/dist/github/code-host.js +105 -0
- package/dist/github/code-host.js.map +1 -0
- package/dist/github/fake-gh.d.ts +17 -0
- package/dist/github/fake-gh.js +51 -0
- package/dist/github/fake-gh.js.map +1 -0
- package/dist/github/fake-github.d.ts +58 -0
- package/dist/github/fake-github.js +285 -0
- package/dist/github/fake-github.js.map +1 -0
- package/dist/github/labels.d.ts +3 -0
- package/dist/github/labels.js +44 -0
- package/dist/github/labels.js.map +1 -0
- package/dist/github/tracker.d.ts +28 -0
- package/dist/github/tracker.js +208 -0
- package/dist/github/tracker.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +18 -0
- package/dist/init.js +217 -0
- package/dist/init.js.map +1 -0
- package/dist/ledger.d.ts +13 -0
- package/dist/ledger.js +49 -0
- package/dist/ledger.js.map +1 -0
- package/dist/main.d.ts +11 -0
- package/dist/main.js +199 -0
- package/dist/main.js.map +1 -0
- package/dist/person-config.d.ts +8 -0
- package/dist/person-config.js +41 -0
- package/dist/person-config.js.map +1 -0
- package/dist/plan.d.ts +9 -0
- package/dist/plan.js +27 -0
- package/dist/plan.js.map +1 -0
- package/dist/ports.d.ts +16 -0
- package/dist/ports.js +104 -0
- package/dist/ports.js.map +1 -0
- package/dist/prompt.d.ts +103 -0
- package/dist/prompt.js +143 -0
- package/dist/prompt.js.map +1 -0
- package/dist/queue.d.ts +20 -0
- package/dist/queue.js +94 -0
- package/dist/queue.js.map +1 -0
- package/dist/say.d.ts +2 -0
- package/dist/say.js +4 -0
- package/dist/say.js.map +1 -0
- package/dist/session.d.ts +39 -0
- package/dist/session.js +144 -0
- package/dist/session.js.map +1 -0
- package/dist/settings.d.ts +4 -0
- package/dist/settings.js +83 -0
- package/dist/settings.js.map +1 -0
- package/dist/signals.d.ts +5 -0
- package/dist/signals.js +13 -0
- package/dist/signals.js.map +1 -0
- package/dist/status-shape.d.ts +53 -0
- package/dist/status-shape.js +3 -0
- package/dist/status-shape.js.map +1 -0
- package/dist/status.d.ts +23 -0
- package/dist/status.js +56 -0
- package/dist/status.js.map +1 -0
- package/dist/tracker.d.ts +56 -0
- package/dist/tracker.js +12 -0
- package/dist/tracker.js.map +1 -0
- package/dist/worktree.d.ts +28 -0
- package/dist/worktree.js +144 -0
- package/dist/worktree.js.map +1 -0
- package/docs/ticket-contract.md +85 -0
- package/package.json +74 -5
- package/plugin/nightjar-status/.claude-plugin/plugin.json +5 -0
- package/plugin/nightjar-status/hooks/format.ts +48 -0
- package/plugin/nightjar-status/hooks/hooks.json +1 -0
- package/plugin/nightjar-status/hooks/register.ts +51 -0
- package/schema/factory.schema.json +330 -0
- package/skills/nightjar-feature/SKILL.md +73 -0
- package/src/status-shape.ts +44 -0
package/dist/checks.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Adapters } from './adapters.js';
|
|
2
|
+
import type { AzureDevOpsRequest } from './azure-devops/index.js';
|
|
3
|
+
import { type Config } from './config.js';
|
|
4
|
+
import { type PersonConfig } from './person-config.js';
|
|
5
|
+
import { type Env } from './git.js';
|
|
6
|
+
export declare class Refusal extends Error {
|
|
7
|
+
}
|
|
8
|
+
export interface Ready {
|
|
9
|
+
readonly root: string;
|
|
10
|
+
readonly config: Config;
|
|
11
|
+
readonly adapters: Adapters;
|
|
12
|
+
readonly me: string;
|
|
13
|
+
readonly baseBranch: string;
|
|
14
|
+
readonly rules: string | null;
|
|
15
|
+
readonly person: PersonConfig;
|
|
16
|
+
readonly assignee: string;
|
|
17
|
+
}
|
|
18
|
+
export interface Line {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly status: 'ok' | 'fail' | 'skip';
|
|
21
|
+
readonly detail: string;
|
|
22
|
+
readonly summary: string | null;
|
|
23
|
+
}
|
|
24
|
+
export interface Checked {
|
|
25
|
+
readonly lines: readonly Line[];
|
|
26
|
+
readonly ready: Ready | null;
|
|
27
|
+
readonly adapters: Adapters | null;
|
|
28
|
+
readonly config: Config | null;
|
|
29
|
+
readonly trackerOk: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface CheckOptions {
|
|
32
|
+
readonly useApiKey: boolean;
|
|
33
|
+
readonly env: Env;
|
|
34
|
+
readonly cwd: string;
|
|
35
|
+
readonly request?: AzureDevOpsRequest;
|
|
36
|
+
readonly failFast: boolean;
|
|
37
|
+
}
|
|
38
|
+
export declare function checkMachine(o: CheckOptions): Promise<Checked>;
|
package/dist/checks.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// `doctor` and `init` run every check and list each; a build stops at the first that fails. Each failure says how to fix it.
|
|
2
|
+
import { makeAdapters } from './adapters.js';
|
|
3
|
+
import { apiKeyProblem } from './args.js';
|
|
4
|
+
import { loadConfig, loadRules } from './config.js';
|
|
5
|
+
import { loadPersonConfig } from './person-config.js';
|
|
6
|
+
import { firstLine, run } from './git.js';
|
|
7
|
+
import { defaultBranch, signing } from './worktree.js';
|
|
8
|
+
import { why } from './say.js';
|
|
9
|
+
// A reason Nightjar will not start on this machine, said as it is.
|
|
10
|
+
export class Refusal extends Error {
|
|
11
|
+
}
|
|
12
|
+
const GH_INSTALL = 'https://cli.github.com/';
|
|
13
|
+
const CLAUDE_INSTALL = 'https://claude.com/claude-code';
|
|
14
|
+
const ghFix = (message) => message.includes('is not on the PATH')
|
|
15
|
+
? `${message} Install it from ${GH_INSTALL}, then run \`gh auth login\`.`
|
|
16
|
+
: `${message} If gh is not signed in, run \`gh auth login\`.`;
|
|
17
|
+
async function need(command, args, cwd, env, what) {
|
|
18
|
+
const got = await run(command, args, cwd, env);
|
|
19
|
+
if (got.missing)
|
|
20
|
+
throw new Refusal(`${command} is not on the PATH.`);
|
|
21
|
+
if (!got.ok)
|
|
22
|
+
throw new Refusal(`${what}: ${firstLine(got.err) || firstLine(got.out)}`);
|
|
23
|
+
return got.out.trim();
|
|
24
|
+
}
|
|
25
|
+
async function claudeVersion(root, env, useApiKey) {
|
|
26
|
+
const got = await run('claude', ['--version'], root, env);
|
|
27
|
+
if (got.missing) {
|
|
28
|
+
throw new Refusal(`claude is not on the PATH. Install Claude Code from ${CLAUDE_INSTALL}, then sign in with \`claude auth login\`.`);
|
|
29
|
+
}
|
|
30
|
+
if (!got.ok)
|
|
31
|
+
throw new Refusal(`claude does not start: ${firstLine(got.err) || firstLine(got.out)}`);
|
|
32
|
+
const version = got.out.trim();
|
|
33
|
+
// a session on the API key needs no login of its own
|
|
34
|
+
if (useApiKey)
|
|
35
|
+
return { version, detail: `${version}, billing ANTHROPIC_API_KEY` };
|
|
36
|
+
const status = await run('claude', ['auth', 'status'], root, env);
|
|
37
|
+
if (!status.ok) {
|
|
38
|
+
throw new Refusal('claude is not signed in: run `claude auth login`. (It is also unsigned if this claude is too old for `claude auth status`.)');
|
|
39
|
+
}
|
|
40
|
+
return { version, detail: `${version}, signed in` };
|
|
41
|
+
}
|
|
42
|
+
export async function checkMachine(o) {
|
|
43
|
+
const lines = [];
|
|
44
|
+
const stopped = () => o.failFast && lines.some((l) => l.status === 'fail');
|
|
45
|
+
async function step(name, fn, said) {
|
|
46
|
+
if (stopped())
|
|
47
|
+
return null;
|
|
48
|
+
try {
|
|
49
|
+
const value = await fn();
|
|
50
|
+
const { detail, summary } = said(value);
|
|
51
|
+
lines.push({ name, status: 'ok', detail, summary: summary === undefined ? detail : summary });
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
catch (fault) {
|
|
55
|
+
// a config fault names its file in every line already
|
|
56
|
+
const detail = why(fault).replace(/^factory\.json: /gm, '');
|
|
57
|
+
lines.push({ name, status: 'fail', detail, summary: null });
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const skip = (name, because) => {
|
|
62
|
+
if (!stopped())
|
|
63
|
+
lines.push({ name, status: 'skip', detail: because, summary: null });
|
|
64
|
+
};
|
|
65
|
+
const keyProblem = apiKeyProblem(o.env, o.useApiKey);
|
|
66
|
+
const key = await step('API key', () => {
|
|
67
|
+
if (keyProblem)
|
|
68
|
+
throw new Refusal(keyProblem);
|
|
69
|
+
return o.useApiKey;
|
|
70
|
+
}, (chosen) => ({
|
|
71
|
+
detail: chosen ? 'ANTHROPIC_API_KEY chosen' : 'none set, so sessions bill your Claude plan',
|
|
72
|
+
summary: chosen ? 'ANTHROPIC_API_KEY chosen' : 'no ANTHROPIC_API_KEY'
|
|
73
|
+
}));
|
|
74
|
+
const node = process.versions.node;
|
|
75
|
+
await step('Node', () => {
|
|
76
|
+
if (Number(node.split('.')[0]) < 24) {
|
|
77
|
+
throw new Refusal(`Node 24 or later is needed, and this is ${node}.`);
|
|
78
|
+
}
|
|
79
|
+
return node;
|
|
80
|
+
}, (version) => ({ detail: version, summary: `Node ${version}` }));
|
|
81
|
+
const root = await step('git checkout', () => need('git', ['rev-parse', '--show-toplevel'], o.cwd, o.env, 'not inside a git checkout'), (path) => ({ detail: path, summary: null }));
|
|
82
|
+
const loaded = root === null
|
|
83
|
+
? null
|
|
84
|
+
: await step('factory.json', () => {
|
|
85
|
+
const config = loadConfig(root);
|
|
86
|
+
return { config, rules: loadRules(root, config) };
|
|
87
|
+
}, () => ({ detail: 'read', summary: 'factory.json' }));
|
|
88
|
+
if (root === null)
|
|
89
|
+
skip('factory.json', 'needs a git checkout');
|
|
90
|
+
const person = await step('config.json', () => loadPersonConfig(o.env), (p) => ({
|
|
91
|
+
detail: `$${String(p.dailyUsd)} a day, building for ${p.assignee ?? 'the signed-in person'}`,
|
|
92
|
+
summary: null
|
|
93
|
+
}));
|
|
94
|
+
let adapters = null;
|
|
95
|
+
let faulty = false;
|
|
96
|
+
if (loaded !== null && root !== null) {
|
|
97
|
+
try {
|
|
98
|
+
adapters = await makeAdapters(loaded.config, root, o.env, o.request);
|
|
99
|
+
}
|
|
100
|
+
catch (fault) {
|
|
101
|
+
faulty = true;
|
|
102
|
+
const detail = why(fault).replace(/^factory\.json: /gm, '');
|
|
103
|
+
if (!stopped()) {
|
|
104
|
+
lines.push({ name: 'Tracker', status: 'fail', detail, summary: null });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
let me = null;
|
|
109
|
+
if (adapters !== null && loaded !== null) {
|
|
110
|
+
const { tracker, codeHost } = loaded.config;
|
|
111
|
+
const github = (type, fix) => (type === 'github' ? fix : why);
|
|
112
|
+
const trackerFix = github(tracker.type, ghFix);
|
|
113
|
+
const hostFix = github(codeHost.type, ghFix);
|
|
114
|
+
const found = adapters;
|
|
115
|
+
me = await step('Tracker', async () => {
|
|
116
|
+
try {
|
|
117
|
+
return await found.tracker.me();
|
|
118
|
+
}
|
|
119
|
+
catch (fault) {
|
|
120
|
+
throw new Refusal(trackerFix(why(fault)));
|
|
121
|
+
}
|
|
122
|
+
}, (person) => ({ detail: found.checked(person) }));
|
|
123
|
+
await step('Code host', async () => {
|
|
124
|
+
try {
|
|
125
|
+
await found.reachCodeHost();
|
|
126
|
+
}
|
|
127
|
+
catch (fault) {
|
|
128
|
+
throw new Refusal(hostFix(why(fault)));
|
|
129
|
+
}
|
|
130
|
+
}, () => ({ detail: found.repo, summary: null }));
|
|
131
|
+
}
|
|
132
|
+
else if (!faulty) {
|
|
133
|
+
skip('Tracker', 'needs a usable factory.json');
|
|
134
|
+
skip('Code host', 'needs a usable factory.json');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
skip('Code host', 'needs a usable factory.json');
|
|
138
|
+
}
|
|
139
|
+
const claude = root === null
|
|
140
|
+
? null
|
|
141
|
+
: await step('claude', () => claudeVersion(root, o.env, o.useApiKey), ({ version, detail }) => ({ detail, summary: `claude ${version}` }));
|
|
142
|
+
const signs = root === null
|
|
143
|
+
? null
|
|
144
|
+
: await step('git signing', async () => {
|
|
145
|
+
const got = await signing(root, o.env);
|
|
146
|
+
if (got === 'fails') {
|
|
147
|
+
throw new Refusal('git cannot sign a commit; unlock your signing key and run again.');
|
|
148
|
+
}
|
|
149
|
+
return got;
|
|
150
|
+
}, (got) => {
|
|
151
|
+
const detail = got === 'signs' ? 'git signs commits' : 'commits unsigned';
|
|
152
|
+
return { detail, summary: detail };
|
|
153
|
+
});
|
|
154
|
+
const trackerOk = me !== null;
|
|
155
|
+
let ready = null;
|
|
156
|
+
if (key !== null &&
|
|
157
|
+
root !== null &&
|
|
158
|
+
loaded !== null &&
|
|
159
|
+
adapters !== null &&
|
|
160
|
+
me !== null &&
|
|
161
|
+
claude !== null &&
|
|
162
|
+
signs !== null &&
|
|
163
|
+
person !== null &&
|
|
164
|
+
lines.every((l) => l.status === 'ok')) {
|
|
165
|
+
const baseBranch = (await defaultBranch(root, o.env)) ?? 'main';
|
|
166
|
+
ready = {
|
|
167
|
+
root,
|
|
168
|
+
config: loaded.config,
|
|
169
|
+
adapters,
|
|
170
|
+
me,
|
|
171
|
+
baseBranch,
|
|
172
|
+
rules: loaded.rules,
|
|
173
|
+
person,
|
|
174
|
+
assignee: person.assignee ?? me
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
return { lines, ready, adapters, config: loaded?.config ?? null, trackerOk };
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runNightjar } from './main.js';
|
|
3
|
+
import { why } from './say.js';
|
|
4
|
+
try {
|
|
5
|
+
process.exit(await runNightjar(process.argv.slice(2)));
|
|
6
|
+
}
|
|
7
|
+
catch (fault) {
|
|
8
|
+
console.error(`nightjar: ${why(fault)}`);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,IAAI,CAAC;IACJ,OAAO,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TicketReference } from './tracker.js';
|
|
2
|
+
export interface Pull {
|
|
3
|
+
readonly id: number;
|
|
4
|
+
readonly url: string;
|
|
5
|
+
}
|
|
6
|
+
export interface DraftRequest {
|
|
7
|
+
readonly title: string;
|
|
8
|
+
readonly head: string;
|
|
9
|
+
readonly base: string;
|
|
10
|
+
readonly body: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CodeHost {
|
|
13
|
+
push(folder: string, branch: string): Promise<void>;
|
|
14
|
+
openPull(branch: string): Promise<Pull | null>;
|
|
15
|
+
createDraft(request: DraftRequest): Promise<Pull>;
|
|
16
|
+
editBody(pull: Pull, body: string): Promise<void>;
|
|
17
|
+
placeReferences(pull: Pull, references: readonly TicketReference[]): Promise<void>;
|
|
18
|
+
comment(pull: Pull, body: string): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-host.js","sourceRoot":"","sources":["../src/code-host.ts"],"names":[],"mappings":""}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type SignalNames } from './signals.js';
|
|
3
|
+
export declare class ConfigError extends Error {
|
|
4
|
+
}
|
|
5
|
+
export declare const CONFIG_FILE = "factory.json";
|
|
6
|
+
export declare const ConfigSchema: z.ZodObject<{
|
|
7
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
8
|
+
tracker: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
9
|
+
type: z.ZodLiteral<"github">;
|
|
10
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
12
|
+
type: z.ZodLiteral<"azure-devops">;
|
|
13
|
+
organization: z.ZodString;
|
|
14
|
+
project: z.ZodString;
|
|
15
|
+
featureType: z.ZodString;
|
|
16
|
+
ticketType: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
18
|
+
type: z.ZodLiteral<"module">;
|
|
19
|
+
path: z.ZodString;
|
|
20
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
+
}, z.core.$strict>], "type">;
|
|
22
|
+
codeHost: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
23
|
+
type: z.ZodLiteral<"github">;
|
|
24
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
26
|
+
type: z.ZodLiteral<"azure-devops">;
|
|
27
|
+
organization: z.ZodString;
|
|
28
|
+
project: z.ZodString;
|
|
29
|
+
repo: z.ZodString;
|
|
30
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
31
|
+
type: z.ZodLiteral<"module">;
|
|
32
|
+
path: z.ZodString;
|
|
33
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
34
|
+
}, z.core.$strict>], "type">;
|
|
35
|
+
check: z.ZodString;
|
|
36
|
+
allowedCommands: z.ZodArray<z.ZodString>;
|
|
37
|
+
rules: z.ZodOptional<z.ZodString>;
|
|
38
|
+
model: z.ZodOptional<z.ZodString>;
|
|
39
|
+
effort: z.ZodOptional<z.ZodString>;
|
|
40
|
+
review: z.ZodOptional<z.ZodObject<{
|
|
41
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
42
|
+
model: z.ZodOptional<z.ZodString>;
|
|
43
|
+
effort: z.ZodOptional<z.ZodString>;
|
|
44
|
+
}, z.core.$strict>>;
|
|
45
|
+
signals: z.ZodPrefault<z.ZodObject<{
|
|
46
|
+
go: z.ZodDefault<z.ZodString>;
|
|
47
|
+
ready: z.ZodDefault<z.ZodString>;
|
|
48
|
+
working: z.ZodDefault<z.ZodString>;
|
|
49
|
+
needsInfo: z.ZodDefault<z.ZodString>;
|
|
50
|
+
human: z.ZodDefault<z.ZodString>;
|
|
51
|
+
}, z.core.$strict>>;
|
|
52
|
+
trusted: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
53
|
+
setup: z.ZodOptional<z.ZodString>;
|
|
54
|
+
ports: z.ZodOptional<z.ZodObject<{
|
|
55
|
+
count: z.ZodNumber;
|
|
56
|
+
env: z.ZodArray<z.ZodString>;
|
|
57
|
+
}, z.core.$strict>>;
|
|
58
|
+
}, z.core.$strict>;
|
|
59
|
+
export type Config = Omit<z.infer<typeof ConfigSchema>, '$schema'> & {
|
|
60
|
+
readonly signals: SignalNames;
|
|
61
|
+
};
|
|
62
|
+
export declare function configJsonSchema(): object;
|
|
63
|
+
export declare function loadRules(root: string, config: Config): string | null;
|
|
64
|
+
export declare const where: (path: readonly PropertyKey[]) => string;
|
|
65
|
+
export declare function loadConfig(root: string): Config;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// factory.json; schema/factory.schema.json is generated from the same definition.
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { DEFAULT_SIGNAL_NAMES, RESERVED_NAMES } from './signals.js';
|
|
6
|
+
import { why } from './say.js';
|
|
7
|
+
export class ConfigError extends Error {
|
|
8
|
+
}
|
|
9
|
+
export const CONFIG_FILE = 'factory.json';
|
|
10
|
+
const repo = z
|
|
11
|
+
.string()
|
|
12
|
+
.regex(/^[^/\s]+\/[^/\s]+$/, 'must be owner/name')
|
|
13
|
+
.optional()
|
|
14
|
+
.meta({ description: 'owner/name on GitHub; when left out, read from the origin remote' });
|
|
15
|
+
const GitHubTracker = z
|
|
16
|
+
.strictObject({ type: z.literal('github'), repo })
|
|
17
|
+
.meta({ description: 'GitHub Issues: a Feature is an issue with sub-issues, its Tickets' });
|
|
18
|
+
const missingOr = (what) => (issue) => issue.input === undefined ? `missing: ${what}` : undefined;
|
|
19
|
+
const named = (what) => z.string({ error: missingOr(what) }).regex(/\S/, what);
|
|
20
|
+
const organization = named('name the organization')
|
|
21
|
+
.regex(/^[^/\s:]+$/, 'the organization name alone, as in dev.azure.com/<organization>')
|
|
22
|
+
.meta({ description: 'The organization, as in dev.azure.com/<organization>' });
|
|
23
|
+
const AzureDevOpsTracker = z
|
|
24
|
+
.strictObject({
|
|
25
|
+
type: z.literal('azure-devops'),
|
|
26
|
+
organization,
|
|
27
|
+
project: named('name the project').meta({ description: 'The project that holds the Features' }),
|
|
28
|
+
featureType: named('name the work item type that plays the Feature').meta({
|
|
29
|
+
description: 'The work item type that plays the Feature, such as Feature, Epic or Product Backlog Item'
|
|
30
|
+
}),
|
|
31
|
+
ticketType: z
|
|
32
|
+
.string()
|
|
33
|
+
.regex(/\S/, 'name the work item type of a Ticket, or leave ticketType out')
|
|
34
|
+
.optional()
|
|
35
|
+
.meta({
|
|
36
|
+
description: 'The work item type nightjar create makes each Ticket as, such as User Story, Product Backlog Item or Issue. Left out, nightjar create makes no Tickets.'
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
.meta({
|
|
40
|
+
description: 'Azure DevOps Boards: a Feature is a work item of featureType, its child work items its Tickets'
|
|
41
|
+
});
|
|
42
|
+
const GitHubCodeHost = z
|
|
43
|
+
.strictObject({ type: z.literal('github'), repo })
|
|
44
|
+
.meta({ description: 'GitHub: the branch is pushed to origin and a draft pull request opened' });
|
|
45
|
+
const AzureReposCodeHost = z
|
|
46
|
+
.strictObject({
|
|
47
|
+
type: z.literal('azure-devops'),
|
|
48
|
+
organization,
|
|
49
|
+
project: named('name the project').meta({ description: 'The project that holds the repo' }),
|
|
50
|
+
repo: named('name the repo').meta({ description: 'The Git repo on Azure Repos, by name' })
|
|
51
|
+
})
|
|
52
|
+
.meta({
|
|
53
|
+
description: 'Azure Repos: the branch is pushed to the repo and a draft pull request opened, signed in as for Azure DevOps Boards'
|
|
54
|
+
});
|
|
55
|
+
// An Adapter the repo brings itself: a module (docs/custom-adapters.md) that builds the Tracker or Code host.
|
|
56
|
+
const adapterModule = (what) => z
|
|
57
|
+
.strictObject({
|
|
58
|
+
type: z.literal('module'),
|
|
59
|
+
path: z
|
|
60
|
+
.string({ error: missingOr('name the module') })
|
|
61
|
+
.regex(/\S/, 'name the module')
|
|
62
|
+
.meta({
|
|
63
|
+
description: `The module that builds the ${what}, as a path from the repo's root`
|
|
64
|
+
}),
|
|
65
|
+
options: z
|
|
66
|
+
.record(z.string(), z.unknown())
|
|
67
|
+
.optional()
|
|
68
|
+
.meta({ description: 'Handed to the module as it is, for its own settings' })
|
|
69
|
+
})
|
|
70
|
+
.meta({ description: `A ${what} of the repo's own, built by a module` });
|
|
71
|
+
const modelField = z.string().regex(/\S/, 'a model is empty').optional();
|
|
72
|
+
const effortField = z.string().regex(/\S/, 'an effort is empty').optional();
|
|
73
|
+
const signalName = (fallback, what) => z
|
|
74
|
+
.string()
|
|
75
|
+
.regex(/\S/, 'a Signal name is empty')
|
|
76
|
+
.refine((name) => !RESERVED_NAMES.includes(name.trim().toLowerCase()), {
|
|
77
|
+
error: 'this is a triage role; Nightjar never reads or sets it'
|
|
78
|
+
})
|
|
79
|
+
.default(fallback)
|
|
80
|
+
.meta({ description: what });
|
|
81
|
+
const Signals = z
|
|
82
|
+
.strictObject({
|
|
83
|
+
go: signalName(DEFAULT_SIGNAL_NAMES.go, 'The Go: put on a Feature assigned to you to have it built. Give it the name of ready to use one mark for both'),
|
|
84
|
+
ready: signalName(DEFAULT_SIGNAL_NAMES.ready, 'A Ticket that is ready to be built'),
|
|
85
|
+
working: signalName(DEFAULT_SIGNAL_NAMES.working, 'Nightjar is working on it'),
|
|
86
|
+
needsInfo: signalName(DEFAULT_SIGNAL_NAMES.needsInfo, 'Nightjar needs an answer to go on'),
|
|
87
|
+
human: signalName(DEFAULT_SIGNAL_NAMES.human, 'A person has to take it from here')
|
|
88
|
+
})
|
|
89
|
+
.prefault({})
|
|
90
|
+
.meta({
|
|
91
|
+
description: 'The name each Signal has on a Tracker: a label on GitHub, a tag on Azure DevOps. Leave out the ones you do not rename. needs-triage and wontfix are refused.'
|
|
92
|
+
});
|
|
93
|
+
export const ConfigSchema = z
|
|
94
|
+
.strictObject({
|
|
95
|
+
$schema: z.string().optional(),
|
|
96
|
+
tracker: z
|
|
97
|
+
.discriminatedUnion('type', [GitHubTracker, AzureDevOpsTracker, adapterModule('Tracker')], {
|
|
98
|
+
error: missingOr('name the Tracker')
|
|
99
|
+
})
|
|
100
|
+
.meta({ description: 'Where the Features and Tickets live' }),
|
|
101
|
+
codeHost: z
|
|
102
|
+
.discriminatedUnion('type', [GitHubCodeHost, AzureReposCodeHost, adapterModule('Code host')], {
|
|
103
|
+
error: missingOr('name the Code host')
|
|
104
|
+
})
|
|
105
|
+
.meta({ description: 'Where the branch is pushed and the draft pull request opened' }),
|
|
106
|
+
check: z
|
|
107
|
+
.string({ error: missingOr('name the command that checks the work') })
|
|
108
|
+
.regex(/\S/, 'name the command that checks the work')
|
|
109
|
+
.meta({
|
|
110
|
+
description: 'The shell command that checks the work in the worktree, run after each Ticket; it fails with a non-zero exit'
|
|
111
|
+
}),
|
|
112
|
+
allowedCommands: z
|
|
113
|
+
.array(z.string().regex(/\S/, 'an allowed command is empty'), {
|
|
114
|
+
error: missingOr('list the commands the agent may run')
|
|
115
|
+
})
|
|
116
|
+
.meta({
|
|
117
|
+
description: 'The commands the agent may run, as Claude Code Bash permission patterns without Bash( ), such as "make test" or "make lint *". Committing, pushing, switching branches, the network and gh stay denied.'
|
|
118
|
+
}),
|
|
119
|
+
rules: z.string().regex(/\S/, 'a rules file path is empty').optional().meta({
|
|
120
|
+
description: 'A text file, relative to the repo root, whose text is added to the agent prompt. Conventions normally live in CLAUDE.md or AGENTS.md.'
|
|
121
|
+
}),
|
|
122
|
+
model: modelField.meta({
|
|
123
|
+
description: "The default model of every session; a Ticket's **Model:** line overrides it and --model overrides both"
|
|
124
|
+
}),
|
|
125
|
+
effort: effortField.meta({
|
|
126
|
+
description: "The default effort of every session; a Ticket's **Effort:** line overrides it and --effort overrides both"
|
|
127
|
+
}),
|
|
128
|
+
review: z
|
|
129
|
+
.strictObject({
|
|
130
|
+
enabled: z
|
|
131
|
+
.boolean()
|
|
132
|
+
.optional()
|
|
133
|
+
.meta({ description: 'false switches the review off; on by default' }),
|
|
134
|
+
model: modelField.meta({
|
|
135
|
+
description: "The review session's own model; else the default model"
|
|
136
|
+
}),
|
|
137
|
+
effort: effortField.meta({
|
|
138
|
+
description: "The review session's own effort; else the default effort"
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
.optional()
|
|
142
|
+
.meta({
|
|
143
|
+
description: 'The read-only review of the whole diff, run before the draft pull request opens'
|
|
144
|
+
}),
|
|
145
|
+
signals: Signals,
|
|
146
|
+
trusted: z.array(z.string().regex(/\S/, 'a trusted login is empty')).optional().meta({
|
|
147
|
+
description: "The logins whose comments reach the agent (on Azure DevOps, sign-in names such as ann@contoso.com). When set, it replaces the Tracker default (GitHub: write access; Azure DevOps: the project's Contributors group); leave it out to keep the default."
|
|
148
|
+
}),
|
|
149
|
+
// worktree setup and reserved ports (N5)
|
|
150
|
+
setup: z.string().regex(/\S/, 'name the setup command, or leave setup out').optional().meta({
|
|
151
|
+
description: 'The shell command run once in each new worktree, before the first session, such as one that installs dependencies. When it fails, the Feature stops with a comment saying why. Left out, nothing is run.'
|
|
152
|
+
}),
|
|
153
|
+
ports: z
|
|
154
|
+
.strictObject({
|
|
155
|
+
count: z.number().int().min(1).max(100).meta({ description: 'How many ports to reserve' }),
|
|
156
|
+
env: z
|
|
157
|
+
.array(z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/, 'not a valid variable name'), {
|
|
158
|
+
error: missingOr('name the environment variables that carry the ports')
|
|
159
|
+
})
|
|
160
|
+
.min(1, 'name at least one environment variable')
|
|
161
|
+
.refine((names) => new Set(names).size === names.length, 'a name is used twice')
|
|
162
|
+
.meta({
|
|
163
|
+
description: 'The environment variables that carry the ports to every session, the check and the setup command: the first name gets the first reserved port, the next name the next port, and so on'
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
.refine((p) => p.env.length <= p.count, {
|
|
167
|
+
path: ['env'],
|
|
168
|
+
error: 'more names than reserved ports'
|
|
169
|
+
})
|
|
170
|
+
.optional()
|
|
171
|
+
.meta({
|
|
172
|
+
description: 'Ports reserved for each run and held for its whole life, so that two runs on one machine never share a port. Left out, no port is held.'
|
|
173
|
+
})
|
|
174
|
+
})
|
|
175
|
+
.meta({ title: 'Nightjar factory.json' });
|
|
176
|
+
export function configJsonSchema() {
|
|
177
|
+
return z.toJSONSchema(ConfigSchema, { io: 'input' });
|
|
178
|
+
}
|
|
179
|
+
// The text of the rules file factory.json names, or null when it names none.
|
|
180
|
+
export function loadRules(root, config) {
|
|
181
|
+
if (config.rules === undefined)
|
|
182
|
+
return null;
|
|
183
|
+
try {
|
|
184
|
+
return readFileSync(join(root, config.rules), 'utf8').trim();
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
throw new ConfigError(`${CONFIG_FILE}: rules: cannot read ${config.rules} in ${root}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export const where = (path) => path.length === 0 ? '' : `${path.map(String).join('.')}: `;
|
|
191
|
+
// The repo's factory.json, or a ConfigError naming each field that is wrong.
|
|
192
|
+
export function loadConfig(root) {
|
|
193
|
+
let text;
|
|
194
|
+
try {
|
|
195
|
+
text = readFileSync(join(root, CONFIG_FILE), 'utf8');
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
throw new ConfigError(`no ${CONFIG_FILE} in ${root}; run \`nightjar init\` to write one`);
|
|
199
|
+
}
|
|
200
|
+
let value;
|
|
201
|
+
try {
|
|
202
|
+
value = JSON.parse(text);
|
|
203
|
+
}
|
|
204
|
+
catch (fault) {
|
|
205
|
+
throw new ConfigError(`${CONFIG_FILE} is not JSON: ${why(fault)}`);
|
|
206
|
+
}
|
|
207
|
+
const parsed = ConfigSchema.safeParse(value);
|
|
208
|
+
if (!parsed.success) {
|
|
209
|
+
const lines = parsed.error.issues.map((i) => `${CONFIG_FILE}: ${where(i.path)}${i.message}`);
|
|
210
|
+
throw new ConfigError(lines.join('\n'));
|
|
211
|
+
}
|
|
212
|
+
const { $schema: _schema, ...config } = parsed.data;
|
|
213
|
+
return config;
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"case.js","sourceRoot":"","sources":["../../src/contract/case.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CodeHost, Pull } from '../code-host.js';
|
|
2
|
+
import type { ContractCase } from './case.js';
|
|
3
|
+
export interface PullView {
|
|
4
|
+
readonly title: string;
|
|
5
|
+
readonly head: string;
|
|
6
|
+
readonly base: string;
|
|
7
|
+
readonly body: string;
|
|
8
|
+
readonly draft: boolean;
|
|
9
|
+
readonly references: readonly string[];
|
|
10
|
+
readonly comments: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
export interface CodeHostSubject {
|
|
13
|
+
readonly codeHost: CodeHost;
|
|
14
|
+
readonly base: string;
|
|
15
|
+
readonly commit: () => Promise<{
|
|
16
|
+
readonly folder: string;
|
|
17
|
+
readonly commit: string;
|
|
18
|
+
}>;
|
|
19
|
+
readonly branch: (name: string) => Promise<string | null>;
|
|
20
|
+
readonly pull: (pull: Pull) => Promise<PullView>;
|
|
21
|
+
readonly close?: () => Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export type CodeHostHarness = () => Promise<CodeHostSubject>;
|
|
24
|
+
export declare const codeHostContract: readonly ContractCase<CodeHostHarness>[];
|