autonomous-sdlc-harness 0.2.0 → 0.4.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/README.md +2 -2
- package/dist/cli.js +0 -0
- package/dist/commands/docs.js +2 -1
- package/dist/commands/docs.js.map +1 -1
- package/dist/commands/doctor.js +27 -6
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +102 -20
- package/dist/commands/init.js.map +1 -1
- package/dist/config/check.js +11 -4
- package/dist/config/check.js.map +1 -1
- package/dist/config/model.js +25 -0
- package/dist/config/model.js.map +1 -1
- package/dist/core/git.js +29 -0
- package/dist/core/git.js.map +1 -1
- package/dist/core/paths.js +22 -2
- package/dist/core/paths.js.map +1 -1
- package/dist/core/prompt.js +6 -2
- package/dist/core/prompt.js.map +1 -1
- package/dist/core/writer.js +2 -0
- package/dist/core/writer.js.map +1 -1
- package/dist/doctor/checks.js +343 -28
- package/dist/doctor/checks.js.map +1 -1
- package/dist/generators/githubWorkflows.js +66 -0
- package/dist/generators/githubWorkflows.js.map +1 -0
- package/dist/generators/notifications.js +105 -19
- package/dist/generators/notifications.js.map +1 -1
- package/dist/generators/outerLoopScripts.js +17 -3
- package/dist/generators/outerLoopScripts.js.map +1 -1
- package/dist/generators/permissionProfile.js +101 -12
- package/dist/generators/permissionProfile.js.map +1 -1
- package/dist/generators/repoRoot.js +18 -2
- package/dist/generators/repoRoot.js.map +1 -1
- package/dist/generators/stateDir.js +9 -3
- package/dist/generators/stateDir.js.map +1 -1
- package/dist/machine/paths.js +4 -1
- package/dist/machine/paths.js.map +1 -1
- package/dist/remote/githubActions.js +86 -0
- package/dist/remote/githubActions.js.map +1 -0
- package/dist/retrieval/queryLog.js +6 -4
- package/dist/retrieval/queryLog.js.map +1 -1
- package/dist/retrieval/runtime.js +12 -22
- package/dist/retrieval/runtime.js.map +1 -1
- package/dist/retrieval/search.js +21 -10
- package/dist/retrieval/search.js.map +1 -1
- package/dist/retrieval/server.js +1 -1
- package/dist/retrieval/setup.js +2 -1
- package/dist/retrieval/setup.js.map +1 -1
- package/package.json +1 -1
- package/templates/README.md +3 -2
- package/templates/claude/context/conventions.md +1 -1
- package/templates/claude/context/layer.md +1 -1
- package/templates/claude/push-notify.env.example +7 -2
- package/templates/claude/settings.autonomous.json +1 -1
- package/templates/github/workflows/harness-resume.yml +124 -0
- package/templates/github/workflows/harness-run.yml +446 -0
- package/templates/repo/gitignore +5 -0
- package/templates/scripts/README.md +1 -1
- package/templates/scripts/autonomous-watcher.sh +1141 -143
- package/templates/scripts/flow-walker.sh +629 -0
- package/templates/scripts/flows/task_plan_writing.graph.json +192 -0
- package/templates/scripts/lib/flow-walker-gates.sh +165 -0
- package/templates/scripts/lib/harness-run-lib.sh +433 -18
- package/templates/scripts/remote-run.sh +1785 -0
- package/templates/scripts/restart-watcher.sh +21 -1
- package/templates/scripts/run-test-suite.sh +182 -0
- package/templates/scripts/scratch-run.sh +2 -1
- package/templates/state-dir/README-root.md +1 -1
- package/templates/state-dir/autonomous_logs/README.md +1 -1
- package/templates/state-dir/improvement_observations/README.md +2 -0
- package/templates/state-dir/scratch/README.md +1 -1
- package/templates/state-dir/test_fix_plan_reviews/README.md +9 -0
- package/templates/state-dir/test_fix_plans/README.md +9 -0
- package/templates/state-dir/test_fix_point_reviews/README.md +9 -0
- package/templates/state-dir/test_run_logs/README.md +11 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Node `>=20.11.0`. Licence Apache-2.0 — `LICENSE` and `NOTICE` ship beside this
|
|
|
12
12
|
|
|
13
13
|
The npm package that carries the harness's **outer loop** — `init`, `doctor`, `config` and `daemon` — and `docs`, the opt-in docs-retrieval search over the docs catalog and conventions documents. The process assets those runs execute — agents, slash commands, hooks, instructions and samples — are not here; they ship as the sibling `plugin/` Claude Code plugin. This package exists at all because a plugin cannot write a repository's `settings.json`, and getting that permission profile right is the highest-friction part of adoption. Installing that plugin is a step of its own, separate from installing this package — see the harness root [`README.md`](https://github.com/firu-daniel/autonomous-sdlc-harness/blob/main/README.md) `## Quick start` for the lettered sequence an adopter runs.
|
|
14
14
|
|
|
15
|
-
**What the five subcommands do.** `init` wires an adopting repository in one deterministic pass: it detects the stack, then writes the configuration, the wrapper scripts, the run-artifact tree, the conventions stubs, the permission profile, the committable project settings, the repository-root files and the pre-push hook — creating what is absent and keeping what the adopter has edited. `doctor` re-checks a wired repository — git and worktrees, that the configured default branch still resolves, the daemon backend, the configuration, the state directory, the ignore rules, which notification settings file the notifier resolves, whether this checkout is in the machine-local registry of installed daemons, the plugin wiring
|
|
15
|
+
**What the five subcommands do.** `init` wires an adopting repository in one deterministic pass: it detects the stack, then writes the configuration, the wrapper scripts, the run-artifact tree, the conventions stubs, the permission profile, the committable project settings, the repository-root files and the pre-push hook — creating what is absent and keeping what the adopter has edited — plus, when `execution.target` is `github-actions`, the two remote-execution workflows `.github/workflows/harness-run.yml` and `.github/workflows/harness-resume.yml`. `doctor` re-checks a wired repository — git and worktrees, that the configured default branch still resolves, the daemon backend, the configuration, the state directory, the ignore rules, which notification settings file the notifier resolves, whether this checkout is in the machine-local registry of installed daemons, the plugin wiring, the permission profile and, offline, the remote-execution setup, which it also asks GitHub about under `--check-github` — and reports every finding, with the exit status as the contract; the remote-execution design is in [`docs/remote-execution.md`](https://github.com/firu-daniel/autonomous-sdlc-harness/blob/main/docs/remote-execution.md); [`docs/cli.md`](https://github.com/firu-daniel/autonomous-sdlc-harness/blob/main/docs/cli.md) §7 is the enumerated list and the severity each check carries. `config` reads and updates one dotted key of `harness.config.json` at a time, refusing a key the file may not carry and backing the file up before each write. `daemon` installs, starts and stops this repository's run daemon on whichever service manager the host has, and lists the repositories on this machine one has been installed for. `docs` builds and queries a local search index over `docs.root` and the conventions documents, and serves it over stdio MCP as `search_docs` when `docs.retrieval` is on. It is **off by default** and opt-in: measured once against agent navigation on a real 1,960-chunk catalog, its verdict was **withdrawn**, and it is kept opt-in by maintainer decision — [`docs/retrieval-eval-results.md`](https://github.com/firu-daniel/autonomous-sdlc-harness/blob/main/docs/retrieval-eval-results.md) → *The decision, applied to the real catalog*; the verb is in [`docs/cli.md`](https://github.com/firu-daniel/autonomous-sdlc-harness/blob/main/docs/cli.md) and the design in [`docs/retrieval.md`](https://github.com/firu-daniel/autonomous-sdlc-harness/blob/main/docs/retrieval.md).
|
|
16
16
|
|
|
17
17
|
Five decisions are recorded here so they are not re-litigated later:
|
|
18
18
|
|
|
@@ -22,4 +22,4 @@ Five decisions are recorded here so they are not re-litigated later:
|
|
|
22
22
|
- **Never shell out to `rm -rf`.** A user-level `permissions.deny` rule on it is realistic, deny is evaluated before any allow and cannot be overridden, so a teardown implemented as a shelled-out `rm -rf` is silently blocked with no useful error. Use Node's in-process `fs.rm` for every removal.
|
|
23
23
|
- **The run watcher's path is derived from `scriptsDir`, not a config key of its own.** `init` writes the watcher into the configured scripts directory with the rest of the outer-loop set, so `daemon` resolves it as `<repoRoot>/<scriptsDir>/autonomous-watcher.sh`: `scriptsDir` is the one key that moves it, and a second key naming the same location could only ever disagree with it. That also keeps the unit's `ExecStart` inside the repository its `WorkingDirectory` names — a CLI run through `npx` lives in a cache directory that can be evicted under a long-running service. `--watcher` overrides the resolution for developing against a watcher that is not the written one. (This decision replaces an earlier package-relative one; `scripts/README.md` records why.)
|
|
24
24
|
|
|
25
|
-
TypeScript in `src/` compiles with `tsc` to `dist/`, which is what `bin` points at; `templates/` holds generator templates and is deliberately outside the compiler's `include`. Two families live there: the **wrapper** scripts `init` renders from a detected command line, and the **outer-loop** shell assets — the run watcher, its restart wrapper, the notifier and its stream formatter, the commit / push / branch-refresh / worktree / cleanup wrappers, the docs-retrieval server launcher and the library they share — which `init` copies verbatim into the same `scriptsDir` because each reads `harness.config.json` at run time. `scripts/` keeps only the daemon unit templates the `daemon` subcommand renders into the account's home directory; it is likewise uncompiled and carried into the published tarball by `files` alongside `templates/` (`scripts/README.md` records why the outer-loop set is not there). A watcher that is missing — deleted, or left behind when `scriptsDir` moved — is a `doctor` warning and a `daemon install` refusal, repaired by re-running `init`.
|
|
25
|
+
TypeScript in `src/` compiles with `tsc` to `dist/`, which is what `bin` points at; `templates/` holds generator templates and is deliberately outside the compiler's `include`. Two script families live there: the **wrapper** scripts `init` renders from a detected command line, and the **outer-loop** shell assets — the run watcher, its restart wrapper, the notifier and its stream formatter, the commit / push / branch-refresh / worktree / cleanup wrappers, the scratch runner, the remote-run client (`remote-run.sh`, which sends a remote run's dispatch, pause, warm-up and stop to GitHub and syncs its state back on demand), the flow walker (`flow-walker.sh`) and its gate library (`lib/flow-walker-gates.sh`), the test-suite runner (`run-test-suite.sh`), the docs-retrieval server launcher and the library they share — which `init` copies verbatim into the same `scriptsDir` because each reads `harness.config.json` at run time, with the planning flow's graph beside them under `flows/`. `templates/github/` holds the two workflows, `harness-run.yml` and `harness-resume.yml`, which `init` writes under `.github/workflows/` only when remote execution is on (`execution.target` is `github-actions`). `scripts/` keeps only the daemon unit templates the `daemon` subcommand renders into the account's home directory; it is likewise uncompiled and carried into the published tarball by `files` alongside `templates/` (`scripts/README.md` records why the outer-loop set is not there). A watcher that is missing — deleted, or left behind when `scriptsDir` moved — is a `doctor` warning and a `daemon install` refusal, repaired by re-running `init`.
|
package/dist/cli.js
CHANGED
|
File without changes
|
package/dist/commands/docs.js
CHANGED
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
import { requireConfig } from '../config/io.js';
|
|
17
17
|
import { EXIT, HarnessError } from '../core/errors.js';
|
|
18
18
|
import { resolveRepoRoot } from '../core/git.js';
|
|
19
|
+
import { ownManifestString } from '../core/paths.js';
|
|
19
20
|
import { DEFAULT_RESULTS, MAX_RESULTS, renderResults, SEARCH_MODES, searchDocs, } from '../retrieval/search.js';
|
|
20
21
|
import { EMBEDDING_MODEL, fetchModels, modelFilesPresent, RERANK_MODEL, RETRIEVAL_STUB_ENV, stubModelsSelected, } from '../retrieval/models.js';
|
|
21
|
-
import {
|
|
22
|
+
import { retrievalModelCacheDir } from '../retrieval/runtime.js';
|
|
22
23
|
import { serveDocs } from '../retrieval/server.js';
|
|
23
24
|
import { openRetrieval } from '../retrieval/session.js';
|
|
24
25
|
const SUMMARY = 'Search the docs catalog and conventions: build the index, query it, serve it over MCP';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EACL,eAAe,EACf,WAAW,EACX,aAAa,EACb,YAAY,EACZ,UAAU,GAEX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
* - **A default run sends nothing.** The `notifications` check is a pure read of whichever settings
|
|
39
39
|
* file the notifier resolves; everything here with network reach is behind a flag —
|
|
40
40
|
* {@link TEST_NOTIFICATION_FLAG}, a delivery, which no default run and no `--dry-run` run makes,
|
|
41
|
-
* and {@link CHECK_REGISTRY_FLAG}
|
|
42
|
-
* suppressed by `--dry-run`. A POST fired by every `doctor` — in CI, from an `&&` chain, from the
|
|
41
|
+
* and {@link CHECK_REGISTRY_FLAG} and {@link CHECK_GITHUB_FLAG}, reads that change nothing anywhere
|
|
42
|
+
* and so are not suppressed by `--dry-run`. A POST fired by every `doctor` — in CI, from an `&&` chain, from the
|
|
43
43
|
* run daemon before it starts a run — would cost the command every property above.
|
|
44
44
|
*/
|
|
45
45
|
import { spawnSync } from 'node:child_process';
|
|
@@ -64,13 +64,21 @@ const TEST_NOTIFICATION_FLAG = '--test-notification';
|
|
|
64
64
|
* air-gapped finds out at the first interactive-test dispatch instead. This flag asks now.
|
|
65
65
|
*/
|
|
66
66
|
const CHECK_REGISTRY_FLAG = '--check-registry';
|
|
67
|
+
/**
|
|
68
|
+
* An option this command takes of its own: it turns on the `remote-github` check's `gh` queries and
|
|
69
|
+
* changes no other check.
|
|
70
|
+
*
|
|
71
|
+
* Off by default for {@link CHECK_REGISTRY_FLAG}'s reason: a default run answers the same in CI,
|
|
72
|
+
* offline and in an `&&` chain, and asking GitHub is a network round trip per question.
|
|
73
|
+
*/
|
|
74
|
+
const CHECK_GITHUB_FLAG = '--check-github';
|
|
67
75
|
/**
|
|
68
76
|
* Every option this command takes of its own, in the order `--help` lists them.
|
|
69
77
|
*
|
|
70
78
|
* Declared as the list rather than spelled into the refusal message, so the message a mistyped flag
|
|
71
79
|
* gets names whatever the command actually accepts and cannot fall behind it.
|
|
72
80
|
*/
|
|
73
|
-
const OWN_FLAGS = Object.freeze([TEST_NOTIFICATION_FLAG, CHECK_REGISTRY_FLAG]);
|
|
81
|
+
const OWN_FLAGS = Object.freeze([TEST_NOTIFICATION_FLAG, CHECK_REGISTRY_FLAG, CHECK_GITHUB_FLAG]);
|
|
74
82
|
/**
|
|
75
83
|
* The event word the test send carries.
|
|
76
84
|
*
|
|
@@ -110,6 +118,8 @@ const DOCTOR_USAGE = Object.freeze([
|
|
|
110
118
|
' autonomous-notify.sh, after the report',
|
|
111
119
|
` ${CHECK_REGISTRY_FLAG} Ask the registry whether each pinned MCP server package can be`,
|
|
112
120
|
' fetched, inside the browser-wiring check',
|
|
121
|
+
` ${CHECK_GITHUB_FLAG} Ask GitHub, through gh, whether the remote-execution setup is`,
|
|
122
|
+
' complete, inside the remote-github check',
|
|
113
123
|
'',
|
|
114
124
|
'A default run sends nothing: the notifications check reads which settings file the notifier',
|
|
115
125
|
`resolves and prints no value from it, and only ${TEST_NOTIFICATION_FLAG} delivers a message. The`,
|
|
@@ -127,6 +137,12 @@ const DOCTOR_USAGE = Object.freeze([
|
|
|
127
137
|
'nothing — and one that cannot be reached warns. It never changes the exit status, and --dry-run',
|
|
128
138
|
'does not suppress it: a metadata read changes nothing, here or anywhere else.',
|
|
129
139
|
'',
|
|
140
|
+
`${CHECK_GITHUB_FLAG} is off by default for the same reason. With it on and execution.target`,
|
|
141
|
+
'github-actions, remote-github asks gh whether it is authenticated, whether GitHub knows',
|
|
142
|
+
'harness-run.yml and harness-resume.yml, which secret names are set (names only, never values) and',
|
|
143
|
+
'which runner HARNESS_RUNNER selects. A call that times out or cannot reach GitHub warns rather than',
|
|
144
|
+
'fails. Every call is a read, so --dry-run does not suppress it either.',
|
|
145
|
+
'',
|
|
130
146
|
'Exit status is the contract — branch on it rather than on the report text:',
|
|
131
147
|
' 0 no check failed: every check passed, or the only findings were warnings',
|
|
132
148
|
' 1 at least one check failed',
|
|
@@ -160,6 +176,7 @@ const DOCTOR_USAGE = Object.freeze([
|
|
|
160
176
|
function parseOptions(argv) {
|
|
161
177
|
let testNotification = false;
|
|
162
178
|
let checkRegistry = false;
|
|
179
|
+
let checkGithub = false;
|
|
163
180
|
for (const token of argv) {
|
|
164
181
|
if (token === TEST_NOTIFICATION_FLAG) {
|
|
165
182
|
testNotification = true;
|
|
@@ -169,11 +186,15 @@ function parseOptions(argv) {
|
|
|
169
186
|
checkRegistry = true;
|
|
170
187
|
continue;
|
|
171
188
|
}
|
|
189
|
+
if (token === CHECK_GITHUB_FLAG) {
|
|
190
|
+
checkGithub = true;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
172
193
|
throw new HarnessError(token.startsWith('-')
|
|
173
|
-
? `doctor: unknown option ${JSON.stringify(token)} — the options doctor takes of its own are ${OWN_FLAGS.join('
|
|
194
|
+
? `doctor: unknown option ${JSON.stringify(token)} — the options doctor takes of its own are ${OWN_FLAGS.join(', ')}; run \`npx autonomous-sdlc-harness doctor --help\` for them and for the global options it accepts`
|
|
174
195
|
: `doctor: unexpected argument ${JSON.stringify(token)} — doctor takes no arguments, and checks the repository containing the current directory (or --cwd)`);
|
|
175
196
|
}
|
|
176
|
-
return { testNotification, checkRegistry };
|
|
197
|
+
return { testNotification, checkRegistry, checkGithub };
|
|
177
198
|
}
|
|
178
199
|
/** `Summary: 9 pass, 3 warn, 0 fail — exit 0 (no check failed; warnings do not fail the command)`. */
|
|
179
200
|
function summaryLine(pass, warn, fail) {
|
|
@@ -300,7 +321,7 @@ function sendTestNotification(ctx, checks) {
|
|
|
300
321
|
*/
|
|
301
322
|
async function run(ctx) {
|
|
302
323
|
const options = parseOptions(ctx.argv);
|
|
303
|
-
const checks = buildCheckContext(ctx.cwd, options.checkRegistry);
|
|
324
|
+
const checks = buildCheckContext(ctx.cwd, options.checkRegistry, options.checkGithub);
|
|
304
325
|
const results = runChecks(checks);
|
|
305
326
|
const width = Math.max(...results.map((result) => result.id.length));
|
|
306
327
|
ctx.report.step(`checks (${ctx.cwd})`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,SAAS,GAGV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAG5F,8FAA8F;AAC9F,MAAM,OAAO,GACX,6GAA6G,CAAC;AAEhH,4EAA4E;AAC5E,MAAM,YAAY,GAAG,EAAE,CAAC;AAExB,uEAAuE;AACvE,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,SAAS,GAAsB,MAAM,CAAC,MAAM,CAAC,CAAC,sBAAsB,EAAE,mBAAmB,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -100,7 +100,7 @@ import { layerGapRemedy, recordedVerdictClause } from '../core/layerGapRemedy.js
|
|
|
100
100
|
import { nameList } from '../core/nameList.js';
|
|
101
101
|
import { insideRepo, packageRoot } from '../core/paths.js';
|
|
102
102
|
import { ANALYZE_COMMAND } from '../core/pluginIdentity.js';
|
|
103
|
-
import { askLine, askYesNo, canPrompt } from '../core/prompt.js';
|
|
103
|
+
import { askLine, askYesNo, canPrompt, REPROMPT_LIMIT } from '../core/prompt.js';
|
|
104
104
|
import { normalizeRepoDir, normalizeRepoPathStrict } from '../core/repoPaths.js';
|
|
105
105
|
import { WritePlan } from '../core/writer.js';
|
|
106
106
|
import { findNestedApplicationDir } from '../detect/nestedApplication.js';
|
|
@@ -108,14 +108,16 @@ import { buildPreset, commandSourceClaim, searchedRoots, SHARED_CONVENTIONS_PATH
|
|
|
108
108
|
import { detectPreset, parsePresetName, FLAT_FALLBACK_SIGNAL_ID, FORCED_SIGNAL_ID, } from '../detect/signals.js';
|
|
109
109
|
import { writeClaudeContext, CLAUDE_MD_PATH, RESERVED_ANALYZE_TARGETS, SETUP_PENDING_OPEN, isUntouchedSkeletonText, } from '../generators/claudeContext.js';
|
|
110
110
|
import { pointHooksPath, writeGitHooks } from '../generators/githooks.js';
|
|
111
|
+
import { writeGithubWorkflows } from '../generators/githubWorkflows.js';
|
|
111
112
|
import { writeHarnessConfig } from '../generators/harnessConfig.js';
|
|
112
|
-
import { writeNotifications,
|
|
113
|
+
import { writeNotifications, PUSH_DESTINATION_FORMS, PUSH_DESTINATION_PLACEHOLDER, resolvePushDestination, UNRECOGNISED_DESTINATION_NOTE, } from '../generators/notifications.js';
|
|
113
114
|
import { writeOuterLoopScripts } from '../generators/outerLoopScripts.js';
|
|
114
|
-
import { writePermissionProfile } from '../generators/permissionProfile.js';
|
|
115
|
+
import { PLUGIN_ROOT_ENTRIES_FLAG, pluginRootEntriesNote, writePermissionProfile, } from '../generators/permissionProfile.js';
|
|
115
116
|
import { writeProjectSettings, MARKETPLACE_FLAG, MARKETPLACE_NAME, MARKETPLACES_KEY, SETTINGS_PATH, SLUG_SHAPE, } from '../generators/projectSettings.js';
|
|
116
117
|
import { writeRepoRootFiles, MCP_PATH } from '../generators/repoRoot.js';
|
|
117
118
|
import { configKeyPath, configuredCommand, wrapperCommandLine, wrapperPath, writeWrapperScripts, WRAPPER_SCRIPTS, } from '../generators/scripts.js';
|
|
118
119
|
import { writeStateDir } from '../generators/stateDir.js';
|
|
120
|
+
import { API_KEY_SECRET, GIT_TOKEN_SECRET, OAUTH_TOKEN_SECRET, PUSH_URL_SECRET, RUNNER_VARIABLE, } from '../remote/githubActions.js';
|
|
119
121
|
import { setUpRetrieval } from '../retrieval/setup.js';
|
|
120
122
|
/** The command's one-line summary, in the usage block and at the head of its own `--help`. */
|
|
121
123
|
const SUMMARY = 'Wire a repository: config, scripts, state tree, permission profile, project settings, conventions stubs';
|
|
@@ -163,6 +165,8 @@ const DAEMON_INSTALL_COMMAND = `${CLI} daemon install`;
|
|
|
163
165
|
* `browserWiringApplies` holds (`doctor/checks.ts`'s browser-wiring check, `commands/doctor.ts`).
|
|
164
166
|
*/
|
|
165
167
|
const DOCTOR_CHECK_REGISTRY_COMMAND = `${DOCTOR_COMMAND} --check-registry`;
|
|
168
|
+
/** The online check of GitHub-side setup, named last in the remote-execution block ({@link reportGithubSteps}). */
|
|
169
|
+
const DOCTOR_CHECK_GITHUB_COMMAND = `${DOCTOR_COMMAND} --check-github`;
|
|
166
170
|
/**
|
|
167
171
|
* How `.mcp.json` launches those servers, as the sentence names it.
|
|
168
172
|
*
|
|
@@ -296,8 +300,9 @@ function initOptions(rows, ..._rowsMissingFor) {
|
|
|
296
300
|
* then the two that decide what is detected, then the values written into the config, then the three
|
|
297
301
|
* phase toggles with their own inputs beside them, then the onboarding slug, then the pair that
|
|
298
302
|
* answers the offer to analyze this repository — which decides the wording the generated
|
|
299
|
-
* always-loaded file carries —
|
|
300
|
-
* unattended run finishes, which is the one pair that writes nothing into the repository at all
|
|
303
|
+
* always-loaded file carries — then the pair that decides whether this account gets told when an
|
|
304
|
+
* unattended run finishes, which is the one pair that writes nothing into the repository at all, and
|
|
305
|
+
* last the switch that adds this machine's plugin-root entries to a freshly generated profile.
|
|
301
306
|
*
|
|
302
307
|
* The first two sit together, and ahead of everything else, because they are the rows whose subject
|
|
303
308
|
* is the **shape of the run** rather than a value in the generated file: one settles what `init` is
|
|
@@ -452,8 +457,14 @@ const INIT_OPTIONS = initOptions([
|
|
|
452
457
|
key: 'pushUrl',
|
|
453
458
|
flag: PUSH_URL_FLAG,
|
|
454
459
|
kind: 'value',
|
|
455
|
-
placeholder:
|
|
456
|
-
summary: '
|
|
460
|
+
placeholder: PUSH_DESTINATION_PLACEHOLDER,
|
|
461
|
+
summary: 'Where notifications are posted: an ntfy topic name, or the full http:// or https:// URL of any endpoint that accepts a POST (with --notifications)',
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
key: 'pluginRootEntries',
|
|
465
|
+
flag: PLUGIN_ROOT_ENTRIES_FLAG,
|
|
466
|
+
kind: 'switch',
|
|
467
|
+
summary: "Include this machine's plugin-root permission entries when the profile is generated (for a remote job)",
|
|
457
468
|
},
|
|
458
469
|
]);
|
|
459
470
|
/**
|
|
@@ -631,6 +642,13 @@ function parseInitFlags(argv) {
|
|
|
631
642
|
const typed = switches.get('docsRetrieval') ?? DOCS_RETRIEVAL_FLAG;
|
|
632
643
|
throw new HarnessError(`init: ${typed} needs --docs: retrieval searches the documentation corpus the docs phase maintains, so it is legal only with that phase on`);
|
|
633
644
|
}
|
|
645
|
+
// Checked here for the reason `qaDriver` is, whether or not --notifications was given: a bad value
|
|
646
|
+
// must not cost an adopter a repository this run created. The value is withheld from the message,
|
|
647
|
+
// unlike {@link parseQaDriver}'s, because a push destination is a credential and stderr is logged.
|
|
648
|
+
const pushUrl = values.get('pushUrl');
|
|
649
|
+
if (pushUrl !== undefined && resolvePushDestination(pushUrl).kind === 'unrecognised') {
|
|
650
|
+
throw new HarnessError(`init: ${PUSH_URL_FLAG} takes ${PUSH_DESTINATION_FORMS}; the value given is neither, so nothing was written. It is not repeated here, because a push destination is a credential — check it and pass it again`);
|
|
651
|
+
}
|
|
634
652
|
return {
|
|
635
653
|
...Object.fromEntries([...values]),
|
|
636
654
|
...(qaDriver === undefined ? {} : { qaDriver: parseQaDriver(qaDriver) }),
|
|
@@ -643,6 +661,7 @@ function parseInitFlags(argv) {
|
|
|
643
661
|
docs: switches.has('docs'),
|
|
644
662
|
docsRetrieval: switches.has('docsRetrieval'),
|
|
645
663
|
parity: switches.has('parity'),
|
|
664
|
+
pluginRootEntries: switches.has('pluginRootEntries'),
|
|
646
665
|
};
|
|
647
666
|
}
|
|
648
667
|
/** The `name` of a JSON manifest, or `undefined` when there is no readable one with a name. */
|
|
@@ -1114,14 +1133,15 @@ function resolveAnalyzeOffer(ctx, flags, repoRoot, config) {
|
|
|
1114
1133
|
*
|
|
1115
1134
|
* The two questions are asked in order and the second only inside the first's yes, because an
|
|
1116
1135
|
* endpoint is meaningless without the opt-in and the opt-in writes nothing without an endpoint. The
|
|
1117
|
-
* endpoint question carries no default
|
|
1118
|
-
*
|
|
1119
|
-
* machine-local file would shadow a repository-side one that already has values
|
|
1120
|
-
* (`generators/notifications.ts`, choice 1)
|
|
1136
|
+
* endpoint question carries no default, and {@link askPushDestination} ends in one of three outcomes:
|
|
1137
|
+
* `undefined`, which routes the run to the generator's guided-setup note rather than to a file —
|
|
1138
|
+
* writing an empty machine-local file would shadow a repository-side one that already has values
|
|
1139
|
+
* (`generators/notifications.ts`, choice 1); a recognised destination, passed on as typed; or, after
|
|
1140
|
+
* the re-asks run out, the last unrecognised answer, on which the generator writes nothing and warns.
|
|
1121
1141
|
*
|
|
1122
1142
|
* A `--push-url` passed **without** the opt-in is left in place rather than dropped here: the
|
|
1123
1143
|
* generator owns what that means and warns about it, as it owns every other line about the artifact
|
|
1124
|
-
* it writes.
|
|
1144
|
+
* it writes. The flag always wins over asking.
|
|
1125
1145
|
*/
|
|
1126
1146
|
function resolveNotifications(ctx, flags) {
|
|
1127
1147
|
const promptCtx = { flags: ctx.flags, report: ctx.report };
|
|
@@ -1132,15 +1152,27 @@ function resolveNotifications(ctx, flags) {
|
|
|
1132
1152
|
flag: NOTIFICATIONS_FLAG,
|
|
1133
1153
|
flagHint: 'to set them up without being asked',
|
|
1134
1154
|
}, promptCtx);
|
|
1135
|
-
const pushUrl = flags.pushUrl ??
|
|
1136
|
-
(enabled
|
|
1137
|
-
? askLine({
|
|
1138
|
-
question: `Where should notifications be posted? (any endpoint that accepts a POST, e.g. ${GUIDED_ENDPOINT_EXAMPLE})`,
|
|
1139
|
-
flag: PUSH_URL_FLAG,
|
|
1140
|
-
}, promptCtx)
|
|
1141
|
-
: undefined);
|
|
1155
|
+
const pushUrl = flags.pushUrl ?? (enabled ? askPushDestination(promptCtx) : undefined);
|
|
1142
1156
|
return pushUrl === undefined ? { enabled } : { enabled, pushUrl };
|
|
1143
1157
|
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Ask for the push destination, re-asking an unrecognised answer up to `REPROMPT_LIMIT` times. Loops
|
|
1160
|
+
* over `askLine` rather than reading the terminal, so `core/prompt.ts` stays the one way to ask.
|
|
1161
|
+
* Returns `undefined` for no answer, a recognised answer as typed, or the last unrecognised one.
|
|
1162
|
+
*/
|
|
1163
|
+
function askPushDestination(promptCtx) {
|
|
1164
|
+
let answer;
|
|
1165
|
+
for (let attempt = 0; attempt <= REPROMPT_LIMIT; attempt += 1) {
|
|
1166
|
+
answer = askLine({
|
|
1167
|
+
question: `Where should notifications be posted? Type ${PUSH_DESTINATION_FORMS}.`,
|
|
1168
|
+
flag: PUSH_URL_FLAG,
|
|
1169
|
+
}, promptCtx);
|
|
1170
|
+
if (answer === undefined || resolvePushDestination(answer).kind !== 'unrecognised')
|
|
1171
|
+
return answer;
|
|
1172
|
+
promptCtx.report.info(UNRECOGNISED_DESTINATION_NOTE);
|
|
1173
|
+
}
|
|
1174
|
+
return answer;
|
|
1175
|
+
}
|
|
1144
1176
|
/** What detection concluded, as one line the summary can carry. */
|
|
1145
1177
|
function detectionLine(detection) {
|
|
1146
1178
|
if (detection.matchedSignal === FORCED_SIGNAL_ID) {
|
|
@@ -1722,6 +1754,9 @@ async function run(ctx) {
|
|
|
1722
1754
|
// exist (`generators/outerLoopScripts.ts`).
|
|
1723
1755
|
const outerLoop = writeOuterLoopScripts({ repoRoot, config: effective, plan });
|
|
1724
1756
|
notes.push(...outerLoop.notes);
|
|
1757
|
+
// After the scripts, which the workflows run, and before the permission profile. Enqueues nothing
|
|
1758
|
+
// unless `execution.target` is `github-actions` (`generators/githubWorkflows.ts`).
|
|
1759
|
+
const workflows = writeGithubWorkflows({ repoRoot, config: effective, plan });
|
|
1725
1760
|
const state = writeStateDir({ repoRoot, config: effective, plan });
|
|
1726
1761
|
notes.push(...state.notes);
|
|
1727
1762
|
// The third of the four questions this run puts, and settled here because its answer is an
|
|
@@ -1766,6 +1801,7 @@ async function run(ctx) {
|
|
|
1766
1801
|
// The run's `--dry-run`, which changes that report's tense and nothing else — the same contract
|
|
1767
1802
|
// the project-file generator above keeps.
|
|
1768
1803
|
dryRun: ctx.flags.dryRun,
|
|
1804
|
+
pluginRootEntries: flags.pluginRootEntries === true,
|
|
1769
1805
|
});
|
|
1770
1806
|
warnings.push(...permissions.warnings);
|
|
1771
1807
|
notes.push(...permissions.notes);
|
|
@@ -1801,7 +1837,11 @@ async function run(ctx) {
|
|
|
1801
1837
|
warnings.push(...hooks.warnings);
|
|
1802
1838
|
notes.push(...hooks.notes);
|
|
1803
1839
|
ctx.report.step(ctx.flags.dryRun ? 'files (dry run — nothing is written)' : 'files');
|
|
1804
|
-
plan.apply({ repoRoot, report: ctx.report, dryRun: ctx.flags.dryRun, force: ctx.flags.force });
|
|
1840
|
+
const applied = plan.apply({ repoRoot, report: ctx.report, dryRun: ctx.flags.dryRun, force: ctx.flags.force });
|
|
1841
|
+
const profileWrite = applied.find((result) => result.path === permissions.path);
|
|
1842
|
+
const pluginRootNote = profileWrite === undefined ? undefined : pluginRootEntriesNote(permissions.pluginRootEntries, profileWrite.effect);
|
|
1843
|
+
if (pluginRootNote !== undefined)
|
|
1844
|
+
notes.push(pluginRootNote);
|
|
1805
1845
|
// After the plan, deliberately: this is the one git-configuration write, and pointing
|
|
1806
1846
|
// `core.hooksPath` at a directory whose hook has not landed yet would enable nothing.
|
|
1807
1847
|
const hooksPath = pointHooksPath({ repoRoot, githooksDir: hooks.githooksDir, dryRun: ctx.flags.dryRun });
|
|
@@ -1835,8 +1875,50 @@ async function run(ctx) {
|
|
|
1835
1875
|
// browser wiring at all. Taken from the one predicate the two generators that write that wiring
|
|
1836
1876
|
// read, never re-spelled here (`config/model.ts`).
|
|
1837
1877
|
browserWiringApplies(effective));
|
|
1878
|
+
// Only the workflows this run created or replaced: a kept one is the adopter's already, and telling
|
|
1879
|
+
// them to commit it again is false on every unforced re-run and in every remote job's `init`.
|
|
1880
|
+
const freshWorkflows = workflows.workflows
|
|
1881
|
+
.filter(({ absolute }) => {
|
|
1882
|
+
const result = applied.find((r) => r.path === absolute);
|
|
1883
|
+
return result !== undefined && result.effect !== 'kept';
|
|
1884
|
+
})
|
|
1885
|
+
.map(({ repoPath }) => repoPath);
|
|
1886
|
+
if (freshWorkflows.length > 0)
|
|
1887
|
+
reportGithubSteps(ctx, effective.defaultBranch, ctx.flags.dryRun, freshWorkflows);
|
|
1838
1888
|
return EXIT.OK;
|
|
1839
1889
|
}
|
|
1890
|
+
/**
|
|
1891
|
+
* The GitHub-side steps only the adopter can take, printed when this run created or replaced at least
|
|
1892
|
+
* one of the two workflows; `workflowPaths` names those, repo-relative.
|
|
1893
|
+
*
|
|
1894
|
+
* Commands stand on their own lines so each can be pasted. The push comes first because GitHub
|
|
1895
|
+
* dispatches a `workflow_dispatch` workflow only once it exists on the default branch.
|
|
1896
|
+
*/
|
|
1897
|
+
function reportGithubSteps(ctx, defaultBranch, dryRun, workflowPaths) {
|
|
1898
|
+
const wrote = dryRun ? 'would write' : 'wrote';
|
|
1899
|
+
const command = (line) => ctx.report.info(` ${line}`);
|
|
1900
|
+
ctx.report.step('remote execution');
|
|
1901
|
+
ctx.report.info(`1. This run ${wrote} ${workflowPaths.join(' and ')}. Commit and push ${workflowPaths.length === 1 ? 'it' : 'both'} to GitHub's default branch (assumed \`${defaultBranch}\` below) — a workflow_dispatch workflow can be dispatched only once it exists there:`);
|
|
1902
|
+
command(`git add ${workflowPaths.join(' ')}`);
|
|
1903
|
+
command('git commit -m "Add the harness workflows"');
|
|
1904
|
+
command(`git push origin ${defaultBranch}`);
|
|
1905
|
+
ctx.report.info('');
|
|
1906
|
+
ctx.report.info(`2. Set one credential secret: ${OAUTH_TOKEN_SECRET} for subscription billing, or ${API_KEY_SECRET} for API billing. When both are set, billing follows ${API_KEY_SECRET}:`);
|
|
1907
|
+
command(`gh secret set ${OAUTH_TOKEN_SECRET}`);
|
|
1908
|
+
command(`gh secret set ${API_KEY_SECRET}`);
|
|
1909
|
+
ctx.report.info('');
|
|
1910
|
+
ctx.report.info(`3. Optionally set ${PUSH_URL_SECRET} to receive push notifications from the job, and ${GIT_TOKEN_SECRET} — a personal or App token — so the job's pushes trigger your own CI, which pushes made with the job's built-in token never do:`);
|
|
1911
|
+
command(`gh secret set ${PUSH_URL_SECRET}`);
|
|
1912
|
+
command(`gh secret set ${GIT_TOKEN_SECRET}`);
|
|
1913
|
+
ctx.report.info('');
|
|
1914
|
+
ctx.report.info(`4. Optionally set the repository variable ${RUNNER_VARIABLE} to run on a self-hosted runner label instead of ubuntu-latest:`);
|
|
1915
|
+
command(`gh variable set ${RUNNER_VARIABLE} --body <runner-label>`);
|
|
1916
|
+
ctx.report.info('');
|
|
1917
|
+
ctx.report.info('5. Then verify the GitHub side:');
|
|
1918
|
+
command(DOCTOR_CHECK_GITHUB_COMMAND);
|
|
1919
|
+
ctx.report.info('');
|
|
1920
|
+
ctx.report.info('Runner choices, costs, billing and security: the harness documentation, docs/remote-execution.md — Remote execution on GitHub Actions.');
|
|
1921
|
+
}
|
|
1840
1922
|
/**
|
|
1841
1923
|
* The caveats, after the action log: the informational lines first, then the ones needing attention.
|
|
1842
1924
|
*
|