@frankzhang2026/opencode-android-orchestrator 0.3.0 → 0.5.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/CHANGELOG.md +29 -0
- package/README.md +81 -20
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/installer/android-project.js +1 -1
- package/dist/installer/android-project.js.map +1 -1
- package/dist/installer/gradle-verification.d.ts +23 -0
- package/dist/installer/gradle-verification.d.ts.map +1 -0
- package/dist/installer/gradle-verification.js +231 -0
- package/dist/installer/gradle-verification.js.map +1 -0
- package/dist/installer/index.d.ts +1 -1
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +1 -1
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/init.d.ts +6 -1
- package/dist/installer/init.d.ts.map +1 -1
- package/dist/installer/init.js +144 -19
- package/dist/installer/init.js.map +1 -1
- package/dist/installer/opencode-config.d.ts +3 -3
- package/dist/installer/opencode-config.js +1 -1
- package/docs/MIGRATION.md +11 -11
- package/docs/SECURITY.md +21 -4
- package/docs/TROUBLESHOOTING.md +28 -2
- package/package.json +1 -1
- package/templates/.opencode/agents/scheduled-coder.md +3 -0
- package/templates/.opencode/agents/scheduled-reviewer.md +5 -4
- package/templates/.opencode/skills/scheduled-quality-coder/SKILL.md +10 -6
- package/templates/.opencode/skills/scheduled-quality-reviewer/SKILL.md +7 -4
- package/templates/AGENTS.md.fragment +4 -0
- package/templates/README.md +16 -0
- package/templates/automation/config.json +1 -0
- package/templates/automation/tasks/TASK-TEMPLATE.json.example +1 -0
- package/templates/scripts/automation/abort-task.sh +5 -10
- package/templates/scripts/automation/accept-and-integrate.sh +1 -1
- package/templates/scripts/automation/acceptance-report.sh +2 -9
- package/templates/scripts/automation/approve-and-run.sh +3 -0
- package/templates/scripts/automation/lib.sh +285 -8
- package/templates/scripts/automation/orchestrate-task.sh +1 -1
- package/templates/scripts/automation/scope-gate.sh +12 -9
- package/templates/scripts/automation/status.sh +4 -0
- package/templates/scripts/automation/tests/run-tests.sh +138 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { detectAndroidProject, } from "./android-project.js";
|
|
5
|
+
export class GradleVerificationDiscoveryError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
details;
|
|
8
|
+
constructor(code, message, details = []) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "GradleVerificationDiscoveryError";
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.details = details;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const DISCOVERY_MARKER = "OPENCODE_ANDROID_ORCHESTRATOR_TASK=";
|
|
16
|
+
const DEFAULT_DISCOVERY_TIMEOUT_MS = 180_000;
|
|
17
|
+
export const GRADLE_TASK_DISCOVERY_INIT_SCRIPT = [
|
|
18
|
+
"gradle.projectsEvaluated {",
|
|
19
|
+
" gradle.rootProject.allprojects.each { project ->",
|
|
20
|
+
" project.tasks.each { task ->",
|
|
21
|
+
" def name = task.name",
|
|
22
|
+
" def relevant =",
|
|
23
|
+
' (name.startsWith("test") && name.endsWith("DebugUnitTest")) ||',
|
|
24
|
+
' name == "assembleDebug" ||',
|
|
25
|
+
' (name.startsWith("assemble") && name.endsWith("Debug")) ||',
|
|
26
|
+
' name == "lint" ||',
|
|
27
|
+
' (name.startsWith("connected") && name.endsWith("DebugAndroidTest"))',
|
|
28
|
+
" if (relevant) {",
|
|
29
|
+
` println("${DISCOVERY_MARKER}" + task.path)`,
|
|
30
|
+
" }",
|
|
31
|
+
" }",
|
|
32
|
+
" }",
|
|
33
|
+
"}",
|
|
34
|
+
"",
|
|
35
|
+
].join("\n");
|
|
36
|
+
function compareStrings(left, right) {
|
|
37
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
38
|
+
}
|
|
39
|
+
function unique(values) {
|
|
40
|
+
return [...new Set(values)];
|
|
41
|
+
}
|
|
42
|
+
function normalizeTaskPath(value) {
|
|
43
|
+
const taskPath = value.trim();
|
|
44
|
+
if (!/^:(?:[A-Za-z0-9_.-]+:)*[A-Za-z][A-Za-z0-9_.-]*$/.test(taskPath)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return taskPath.indexOf(":", 1) < 0 ? taskPath.slice(1) : taskPath;
|
|
48
|
+
}
|
|
49
|
+
export function parseGradleTaskPaths(stdout) {
|
|
50
|
+
const paths = stdout
|
|
51
|
+
.split(/\r?\n/)
|
|
52
|
+
.filter((line) => line.startsWith(DISCOVERY_MARKER))
|
|
53
|
+
.map((line) => normalizeTaskPath(line.slice(DISCOVERY_MARKER.length)))
|
|
54
|
+
.filter((path) => path !== null);
|
|
55
|
+
return unique(paths).sort(compareStrings);
|
|
56
|
+
}
|
|
57
|
+
function taskRecord(path) {
|
|
58
|
+
const separator = path.lastIndexOf(":");
|
|
59
|
+
return separator < 0
|
|
60
|
+
? { path, modulePath: ":", name: path }
|
|
61
|
+
: {
|
|
62
|
+
path,
|
|
63
|
+
modulePath: path.slice(0, separator),
|
|
64
|
+
name: path.slice(separator + 1),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function normalizedIdentifier(value) {
|
|
68
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
69
|
+
}
|
|
70
|
+
function moduleName(module) {
|
|
71
|
+
return module.gradlePath.split(":").filter(Boolean).at(-1) ?? "";
|
|
72
|
+
}
|
|
73
|
+
function preferredModulePath(detection, requestedPrimaryModule) {
|
|
74
|
+
if (requestedPrimaryModule !== undefined &&
|
|
75
|
+
detection.modules.some((module) => module.gradlePath === requestedPrimaryModule)) {
|
|
76
|
+
return requestedPrimaryModule;
|
|
77
|
+
}
|
|
78
|
+
const applications = detection.modules.filter((module) => module.type === "application");
|
|
79
|
+
const onlyApplication = applications[0];
|
|
80
|
+
if (applications.length === 1 && onlyApplication !== undefined) {
|
|
81
|
+
return onlyApplication.gradlePath;
|
|
82
|
+
}
|
|
83
|
+
const projectName = normalizedIdentifier(detection.projectName ?? "");
|
|
84
|
+
const matchingApplication = applications.find((module) => {
|
|
85
|
+
const name = normalizedIdentifier(moduleName(module));
|
|
86
|
+
return name.length > 0 && projectName.includes(name);
|
|
87
|
+
});
|
|
88
|
+
return (matchingApplication ??
|
|
89
|
+
applications[0] ??
|
|
90
|
+
detection.modules[0])?.gradlePath ?? ":";
|
|
91
|
+
}
|
|
92
|
+
function moduleType(modules, modulePath) {
|
|
93
|
+
return modules.get(modulePath)?.type ?? null;
|
|
94
|
+
}
|
|
95
|
+
function variantName(taskName, prefix, suffix) {
|
|
96
|
+
return taskName.slice(prefix.length, -suffix.length);
|
|
97
|
+
}
|
|
98
|
+
function preferenceScore(task, detection, modules, preferredModule, prefix, suffix) {
|
|
99
|
+
let score = 0;
|
|
100
|
+
if (task.modulePath === preferredModule) {
|
|
101
|
+
score += 100;
|
|
102
|
+
}
|
|
103
|
+
if (moduleType(modules, task.modulePath) === "application") {
|
|
104
|
+
score += 20;
|
|
105
|
+
}
|
|
106
|
+
const variant = normalizedIdentifier(variantName(task.name, prefix, suffix));
|
|
107
|
+
if (variant.length === 0) {
|
|
108
|
+
score += 10;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const preferred = modules.get(preferredModule) ?? detection.modules[0];
|
|
112
|
+
const tokens = unique([
|
|
113
|
+
preferred === undefined
|
|
114
|
+
? ""
|
|
115
|
+
: normalizedIdentifier(moduleName(preferred)),
|
|
116
|
+
normalizedIdentifier(detection.projectName ?? ""),
|
|
117
|
+
]).filter((token) => token.length > 0);
|
|
118
|
+
if (tokens.some((token) => variant.includes(token) || token.includes(variant))) {
|
|
119
|
+
score += 30;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return score;
|
|
123
|
+
}
|
|
124
|
+
function sortByPreference(tasks, detection, modules, preferredModule, prefix, suffix) {
|
|
125
|
+
return [...tasks].sort((left, right) => {
|
|
126
|
+
const scoreDifference = preferenceScore(right, detection, modules, preferredModule, prefix, suffix) -
|
|
127
|
+
preferenceScore(left, detection, modules, preferredModule, prefix, suffix);
|
|
128
|
+
return scoreDifference !== 0
|
|
129
|
+
? scoreDifference
|
|
130
|
+
: compareStrings(left.path, right.path);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function commandDetails(result) {
|
|
134
|
+
return [
|
|
135
|
+
`Exit status: ${String(result.status)}`,
|
|
136
|
+
result.error,
|
|
137
|
+
result.stderr.trim(),
|
|
138
|
+
result.stdout.trim(),
|
|
139
|
+
]
|
|
140
|
+
.filter((detail) => detail !== null && detail.length > 0)
|
|
141
|
+
.map((detail) => detail.length <= 2_000 ? detail : `[truncated]\n${detail.slice(-2_000)}`);
|
|
142
|
+
}
|
|
143
|
+
export function inferGradleVerificationConfiguration(detection, taskPaths, requestedPrimaryModule) {
|
|
144
|
+
if (detection.modules.length === 0) {
|
|
145
|
+
throw new GradleVerificationDiscoveryError("GRADLE_PROJECT_INVALID", "At least one detected Android module is required for task inference.");
|
|
146
|
+
}
|
|
147
|
+
const modules = new Map(detection.modules.map((module) => [module.gradlePath, module]));
|
|
148
|
+
const tasks = taskPaths
|
|
149
|
+
.map(taskRecord)
|
|
150
|
+
.filter((task) => modules.has(task.modulePath));
|
|
151
|
+
const preferredModule = preferredModulePath(detection, requestedPrimaryModule);
|
|
152
|
+
const unitTasks = sortByPreference(tasks.filter((task) => /^test(?:[A-Z][A-Za-z0-9]*)?DebugUnitTest$/.test(task.name)), detection, modules, preferredModule, "test", "DebugUnitTest");
|
|
153
|
+
const deviceTasks = sortByPreference(tasks.filter((task) => /^connected(?:[A-Z][A-Za-z0-9]*)?DebugAndroidTest$/.test(task.name)), detection, modules, preferredModule, "connected", "DebugAndroidTest");
|
|
154
|
+
const assembleTasks = tasks.filter((task) => /^assemble(?:[A-Z][A-Za-z0-9]*)?Debug$/.test(task.name));
|
|
155
|
+
const lintTasks = tasks.filter((task) => task.name === "lint");
|
|
156
|
+
const fullUnitTestTasks = [
|
|
157
|
+
...(unitTasks.some((task) => task.name === "testDebugUnitTest")
|
|
158
|
+
? ["testDebugUnitTest"]
|
|
159
|
+
: []),
|
|
160
|
+
...unitTasks
|
|
161
|
+
.filter((task) => task.name !== "testDebugUnitTest")
|
|
162
|
+
.map((task) => task.path),
|
|
163
|
+
];
|
|
164
|
+
const focusedTestTasks = unitTasks.map((task) => task.path);
|
|
165
|
+
const selectedAssembleTasks = assembleTasks.some((task) => task.name === "assembleDebug")
|
|
166
|
+
? ["assembleDebug"]
|
|
167
|
+
: assembleTasks.map((task) => task.path).sort(compareStrings);
|
|
168
|
+
const selectedLintTasks = lintTasks.length > 0 ? ["lint"] : [];
|
|
169
|
+
const deviceTestTasks = [
|
|
170
|
+
...(deviceTasks.some((task) => task.name === "connectedDebugAndroidTest")
|
|
171
|
+
? ["connectedDebugAndroidTest"]
|
|
172
|
+
: []),
|
|
173
|
+
...deviceTasks
|
|
174
|
+
.filter((task) => task.name !== "connectedDebugAndroidTest")
|
|
175
|
+
.map((task) => task.path),
|
|
176
|
+
];
|
|
177
|
+
const configuration = {
|
|
178
|
+
fullUnitTestTasks: unique(fullUnitTestTasks),
|
|
179
|
+
focusedTestTasks: unique(focusedTestTasks),
|
|
180
|
+
assembleTasks: unique(selectedAssembleTasks),
|
|
181
|
+
lintTasks: unique(selectedLintTasks),
|
|
182
|
+
deviceTestTasks: unique(deviceTestTasks),
|
|
183
|
+
};
|
|
184
|
+
const missingGroups = Object.entries(configuration)
|
|
185
|
+
.filter(([, values]) => values.length === 0)
|
|
186
|
+
.map(([name]) => name);
|
|
187
|
+
if (missingGroups.length > 0) {
|
|
188
|
+
throw new GradleVerificationDiscoveryError("GRADLE_TASK_MATRIX_INCOMPLETE", "Gradle task discovery could not build a complete Android verification matrix.", [
|
|
189
|
+
`Missing task groups: ${missingGroups.join(", ")}`,
|
|
190
|
+
`Detected relevant tasks: ${tasks.map((task) => task.path).join(", ") || "none"}`,
|
|
191
|
+
]);
|
|
192
|
+
}
|
|
193
|
+
return configuration;
|
|
194
|
+
}
|
|
195
|
+
export function discoverGradleVerificationConfiguration(targetDirectory, runner, options = {}) {
|
|
196
|
+
const detection = detectAndroidProject(targetDirectory);
|
|
197
|
+
if (!detection.isAndroidProject ||
|
|
198
|
+
detection.projectRoot === null ||
|
|
199
|
+
detection.gradleWrapper === null ||
|
|
200
|
+
!detection.gradleWrapper.complete) {
|
|
201
|
+
throw new GradleVerificationDiscoveryError("GRADLE_PROJECT_INVALID", "A complete Android Gradle project is required for task discovery.", [...detection.errors, ...detection.warnings]);
|
|
202
|
+
}
|
|
203
|
+
const temporaryDirectory = mkdtempSync(join(tmpdir(), "opencode-android-orchestrator-gradle-"));
|
|
204
|
+
const initScript = join(temporaryDirectory, "discover-tasks.init.gradle");
|
|
205
|
+
try {
|
|
206
|
+
writeFileSync(initScript, GRADLE_TASK_DISCOVERY_INIT_SCRIPT, {
|
|
207
|
+
encoding: "utf8",
|
|
208
|
+
flag: "wx",
|
|
209
|
+
mode: 0o600,
|
|
210
|
+
});
|
|
211
|
+
const result = runner(detection.gradleWrapper.script, [
|
|
212
|
+
"help",
|
|
213
|
+
"--init-script",
|
|
214
|
+
initScript,
|
|
215
|
+
"--console=plain",
|
|
216
|
+
"--quiet",
|
|
217
|
+
], {
|
|
218
|
+
cwd: detection.projectRoot,
|
|
219
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_DISCOVERY_TIMEOUT_MS,
|
|
220
|
+
});
|
|
221
|
+
if (result.error !== null || result.status !== 0) {
|
|
222
|
+
throw new GradleVerificationDiscoveryError("GRADLE_TASK_DISCOVERY_FAILED", "Gradle could not enumerate Android verification tasks.", commandDetails(result));
|
|
223
|
+
}
|
|
224
|
+
const taskPaths = parseGradleTaskPaths(result.stdout);
|
|
225
|
+
return inferGradleVerificationConfiguration(detection, taskPaths, options.primaryModule);
|
|
226
|
+
}
|
|
227
|
+
finally {
|
|
228
|
+
rmSync(temporaryDirectory, { recursive: true, force: true });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=gradle-verification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradle-verification.js","sourceRoot":"","sources":["../../src/installer/gradle-verification.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ export interface InstallerRequest {
|
|
|
6
6
|
export { AGENTS_MANAGED_BLOCK_BEGIN, AGENTS_MANAGED_BLOCK_END, AgentsConfigMergeError, mergeAgentsConfigText, planAgentsConfigMerge, type AgentsConfigMergeErrorCode, type AgentsConfigMergePlan, } from "./agents-config.js";
|
|
7
7
|
export { AdaptiveProjectTemplateError, DEFAULT_MODULE_SCOPE, isModuleScope, planAdaptiveProjectTemplates, type AdaptiveAndroidModuleConfiguration, type AdaptiveAndroidProjectConfiguration, type AdaptiveAutomationConfiguration, type AdaptiveProjectTemplateErrorCode, type AdaptiveProjectTemplateOptions, type AdaptiveProjectTemplatePlan, type AdaptiveTargetTest, type AdaptiveTaskContractExample, type GradleVerificationConfiguration, type ModuleScope, } from "./adaptive-templates.js";
|
|
8
8
|
export { detectAndroidProject, type AndroidModuleDetection, type AndroidModuleType, type AndroidProjectDetection, type GradleDsl, type GradleWrapperDetection, } from "./android-project.js";
|
|
9
|
-
export { ProjectInitializationError, formatProjectInitializationResult, planProjectInitialization, planProjectResourceInputs, runInitProcess, runProjectInitialization, verifyInitializedProject, type InitProcessOptions, type InitProcessRunner, type InitVerificationCheck, type InitVerificationReport, type InitVerificationStatus, type ProjectInitializationErrorCode, type ProjectInitializationOptions, type ProjectInitializationPlan, type ProjectInitializationResult, type ProjectResourceInputPlan, } from "./init.js";
|
|
9
|
+
export { INITIAL_WORKTREE_ALLOWLIST_CONTENT, ProjectInitializationError, WORKTREE_ALLOWLIST_RELATIVE_PATH, formatProjectInitializationResult, planProjectInitialization, planProjectResourceInputs, runInitProcess, runProjectInitialization, verifyInitializedProject, type InitProcessOptions, type InitProcessRunner, type InitVerificationCheck, type InitVerificationReport, type InitVerificationStatus, type ProjectInitializationErrorCode, type ProjectInitializationOptions, type ProjectInitializationPlan, type ProjectInitializationResult, type ProjectResourceInputPlan, type WorktreeAllowlistInitializationStatus, } from "./init.js";
|
|
10
10
|
export { INSTALLATION_BACKUPS_DIRECTORY, INSTALLATION_CONTROL_DIRECTORY, INSTALLATION_HISTORY_DIRECTORY, INSTALLATION_MANIFEST_RELATIVE_PATH, INSTALLATION_MANIFEST_SCHEMA_VERSION, InstallationManifestError, applyInstallationPlan, completeInstallationManifest, detectInstallationConflicts, planInstallationPreparation, prepareInstallationBackup, readInstallationManifest, rollbackPreparedInstallation, verifyInstallationIntegrity, type AppliedInstallation, type InstallationApplyOptions, type InstallationCompletionOptions, type InstallationConflictKind, type InstallationConflictReport, type InstallationFileConflict, type InstallationFileInput, type InstallationFileStrategy, type InstallationIntegrityCheck, type InstallationIntegrityReport, type InstallationIntegrityStatus, type InstallationManifest, type InstallationManifestErrorCode, type InstallationManifestFile, type InstallationManifestState, type InstallationPreparationOptions, type InstallationPreparationPlan, type InstallationRollbackOptions, type PlannedInstallationFile, type PreparedInstallation, type PreviousInstallationFile, } from "./install-manifest.js";
|
|
11
11
|
export { UPGRADE_MARKER_RELATIVE_PATH, UPGRADE_RECOVERY_DIRECTORY, ProjectUpgradeError, applyProjectUpgrade, formatProjectUpgradeResult, planProjectUpgrade, runProjectUpgrade, type AppliedProjectUpgrade, type PlannedUpgradeFile, type PlannedUpgradeRemoval, type ProjectUpgradeErrorCode, type ProjectUpgradeOptions, type ProjectUpgradePlan, type ProjectUpgradeResult, type UpgradeFileSnapshot, } from "./upgrade.js";
|
|
12
12
|
export { UNINSTALL_MARKER_RELATIVE_PATH, UNINSTALL_RECOVERY_DIRECTORY, ProjectUninstallError, applyProjectUninstall, formatProjectUninstallResult, planProjectUninstall, runProjectUninstall, type AppliedProjectUninstall, type PlannedUninstallFile, type ProjectUninstallErrorCode, type ProjectUninstallOptions, type ProjectUninstallPlan, type ProjectUninstallResult, type UninstallFileDisposition, type UninstallFileSnapshot, } from "./uninstall.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/installer/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;AAE3E,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,GAC3B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,aAAa,EACb,4BAA4B,EAC5B,KAAK,kCAAkC,EACvC,KAAK,mCAAmC,EACxC,KAAK,+BAA+B,EACpC,KAAK,gCAAgC,EACrC,KAAK,8BAA8B,EACnC,KAAK,2BAA2B,EAChC,KAAK,kBAAkB,EACvB,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,KAAK,WAAW,GACjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,oBAAoB,EACpB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,SAAS,EACd,KAAK,sBAAsB,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,0BAA0B,EAC1B,iCAAiC,EACjC,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACd,wBAAwB,EACxB,wBAAwB,EACxB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,8BAA8B,EACnC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/installer/index.ts"],"names":[],"mappings":"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"}
|
package/dist/installer/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { AGENTS_MANAGED_BLOCK_BEGIN, AGENTS_MANAGED_BLOCK_END, AgentsConfigMergeError, mergeAgentsConfigText, planAgentsConfigMerge, } from "./agents-config.js";
|
|
2
2
|
export { AdaptiveProjectTemplateError, DEFAULT_MODULE_SCOPE, isModuleScope, planAdaptiveProjectTemplates, } from "./adaptive-templates.js";
|
|
3
3
|
export { detectAndroidProject, } from "./android-project.js";
|
|
4
|
-
export { ProjectInitializationError, formatProjectInitializationResult, planProjectInitialization, planProjectResourceInputs, runInitProcess, runProjectInitialization, verifyInitializedProject, } from "./init.js";
|
|
4
|
+
export { INITIAL_WORKTREE_ALLOWLIST_CONTENT, ProjectInitializationError, WORKTREE_ALLOWLIST_RELATIVE_PATH, formatProjectInitializationResult, planProjectInitialization, planProjectResourceInputs, runInitProcess, runProjectInitialization, verifyInitializedProject, } from "./init.js";
|
|
5
5
|
export { INSTALLATION_BACKUPS_DIRECTORY, INSTALLATION_CONTROL_DIRECTORY, INSTALLATION_HISTORY_DIRECTORY, INSTALLATION_MANIFEST_RELATIVE_PATH, INSTALLATION_MANIFEST_SCHEMA_VERSION, InstallationManifestError, applyInstallationPlan, completeInstallationManifest, detectInstallationConflicts, planInstallationPreparation, prepareInstallationBackup, readInstallationManifest, rollbackPreparedInstallation, verifyInstallationIntegrity, } from "./install-manifest.js";
|
|
6
6
|
export { UPGRADE_MARKER_RELATIVE_PATH, UPGRADE_RECOVERY_DIRECTORY, ProjectUpgradeError, applyProjectUpgrade, formatProjectUpgradeResult, planProjectUpgrade, runProjectUpgrade, } from "./upgrade.js";
|
|
7
7
|
export { UNINSTALL_MARKER_RELATIVE_PATH, UNINSTALL_RECOVERY_DIRECTORY, ProjectUninstallError, applyProjectUninstall, formatProjectUninstallResult, planProjectUninstall, runProjectUninstall, } from "./uninstall.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/installer/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,aAAa,EACb,4BAA4B,GAW7B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,oBAAoB,GAMrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,0BAA0B,EAC1B,iCAAiC,EACjC,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACd,wBAAwB,EACxB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/installer/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,GAGtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,aAAa,EACb,4BAA4B,GAW7B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,oBAAoB,GAMrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,kCAAkC,EAClC,0BAA0B,EAC1B,gCAAgC,EAChC,iCAAiC,EACjC,yBAAyB,EACzB,yBAAyB,EACzB,cAAc,EACd,wBAAwB,EACxB,wBAAwB,GAYzB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,8BAA8B,EAC9B,mCAAmC,EACnC,oCAAoC,EACpC,yBAAyB,EACzB,qBAAqB,EACrB,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,yBAAyB,EACzB,wBAAwB,EACxB,4BAA4B,EAC5B,2BAA2B,GAsB5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,GASlB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC5B,qBAAqB,EACrB,qBAAqB,EACrB,4BAA4B,EAC5B,oBAAoB,EACpB,mBAAmB,GASpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,yBAAyB,EACzB,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,EAC1B,0BAA0B,EAC1B,4BAA4B,EAC5B,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,GAKtB,MAAM,sBAAsB,CAAC"}
|
package/dist/installer/init.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { type AdaptiveProjectTemplateOptions, type AdaptiveProjectTemplatePlan,
|
|
|
3
3
|
import { type AgentsConfigMergePlan } from "./agents-config.js";
|
|
4
4
|
import { type InstallationFileInput, type InstallationManifest, type InstallationPreparationPlan } from "./install-manifest.js";
|
|
5
5
|
import { type OpenCodeConfigMergePlan } from "./opencode-config.js";
|
|
6
|
-
export
|
|
6
|
+
export declare const WORKTREE_ALLOWLIST_RELATIVE_PATH = ".automation-worktree-allowlist";
|
|
7
|
+
export declare const INITIAL_WORKTREE_ALLOWLIST_CONTENT: string;
|
|
8
|
+
export type ProjectInitializationErrorCode = "DOCTOR_FAILED" | "EXISTING_INSTALLATION_DIFFERENT" | "EXISTING_INSTALLATION_INVALID" | "GRADLE_DISCOVERY_FAILED" | "POST_INSTALL_VERIFICATION_FAILED" | "TEMPLATE_INVALID" | "WORKTREE_ALLOWLIST_INVALID" | "WORKTREE_ALLOWLIST_ROLLBACK_FAILED" | "WORKTREE_ALLOWLIST_WRITE_FAILED";
|
|
7
9
|
export declare class ProjectInitializationError extends Error {
|
|
8
10
|
readonly code: ProjectInitializationErrorCode;
|
|
9
11
|
readonly details: readonly string[];
|
|
@@ -55,10 +57,13 @@ export interface ProjectInitializationResult {
|
|
|
55
57
|
managedFileCount: number;
|
|
56
58
|
writtenFileCount: number;
|
|
57
59
|
reusedFileCount: number;
|
|
60
|
+
worktreeAllowlistPath: string;
|
|
61
|
+
worktreeAllowlistStatus: WorktreeAllowlistInitializationStatus;
|
|
58
62
|
manifest: InstallationManifest;
|
|
59
63
|
doctor: DoctorReport;
|
|
60
64
|
verification: InitVerificationReport;
|
|
61
65
|
}
|
|
66
|
+
export type WorktreeAllowlistInitializationStatus = "created" | "existing";
|
|
62
67
|
export declare const runInitProcess: InitProcessRunner;
|
|
63
68
|
export declare function planProjectResourceInputs(directory: string, options?: AdaptiveProjectTemplateOptions): ProjectResourceInputPlan;
|
|
64
69
|
export declare function planProjectInitialization(directory: string, options?: ProjectInitializationOptions): ProjectInitializationPlan;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/installer/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/installer/init.ts"],"names":[],"mappings":"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"}
|
package/dist/installer/init.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
-
import { lstatSync, readdirSync, readFileSync, } from "node:fs";
|
|
2
|
+
import { lstatSync, readdirSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import { isAbsolute, join, relative, resolve, sep, } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { formatDoctorReport, runDoctor, } from "../doctor/index.js";
|
|
6
6
|
import { planAdaptiveProjectTemplates, } from "./adaptive-templates.js";
|
|
7
|
+
import { GradleVerificationDiscoveryError, discoverGradleVerificationConfiguration, } from "./gradle-verification.js";
|
|
7
8
|
import { planAgentsConfigMerge, } from "./agents-config.js";
|
|
8
9
|
import { INSTALLATION_MANIFEST_RELATIVE_PATH, InstallationManifestError, applyInstallationPlan, planInstallationPreparation, readInstallationManifest, verifyInstallationIntegrity, } from "./install-manifest.js";
|
|
9
10
|
import { ORCHESTRATOR_PACKAGE_NAME, ORCHESTRATOR_PACKAGE_VERSION, planOpenCodeConfigMerge, } from "./opencode-config.js";
|
|
@@ -16,6 +17,12 @@ const TEMPLATE_COPY_FILES = [
|
|
|
16
17
|
"automation/task-contract.schema.json",
|
|
17
18
|
"docs/plans/README.md",
|
|
18
19
|
];
|
|
20
|
+
export const WORKTREE_ALLOWLIST_RELATIVE_PATH = ".automation-worktree-allowlist";
|
|
21
|
+
export const INITIAL_WORKTREE_ALLOWLIST_CONTENT = [
|
|
22
|
+
"# Optional: one exact repository-relative file path per line.",
|
|
23
|
+
"# Blank lines and lines beginning with # are ignored.",
|
|
24
|
+
"",
|
|
25
|
+
].join("\n");
|
|
19
26
|
export class ProjectInitializationError extends Error {
|
|
20
27
|
code;
|
|
21
28
|
details;
|
|
@@ -43,6 +50,82 @@ export const runInitProcess = (executable, args, options) => {
|
|
|
43
50
|
function comparePaths(left, right) {
|
|
44
51
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
45
52
|
}
|
|
53
|
+
function filesystemErrorCode(error) {
|
|
54
|
+
if (typeof error === "object" &&
|
|
55
|
+
error !== null &&
|
|
56
|
+
"code" in error &&
|
|
57
|
+
typeof error.code === "string") {
|
|
58
|
+
return error.code;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
function assertExistingWorktreeAllowlistIsRegular(path) {
|
|
63
|
+
let stats;
|
|
64
|
+
try {
|
|
65
|
+
stats = lstatSync(path);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
throw new ProjectInitializationError("WORKTREE_ALLOWLIST_WRITE_FAILED", `Unable to inspect the worktree allowlist: ${path}`, [error instanceof Error ? error.message : String(error)]);
|
|
69
|
+
}
|
|
70
|
+
if (stats.isSymbolicLink() || !stats.isFile()) {
|
|
71
|
+
throw new ProjectInitializationError("WORKTREE_ALLOWLIST_INVALID", "The worktree allowlist must be a regular file, not a symlink or directory.", [path]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function initializeWorktreeAllowlist(targetDirectory) {
|
|
75
|
+
const path = join(targetDirectory, WORKTREE_ALLOWLIST_RELATIVE_PATH);
|
|
76
|
+
try {
|
|
77
|
+
lstatSync(path);
|
|
78
|
+
assertExistingWorktreeAllowlistIsRegular(path);
|
|
79
|
+
return { path, status: "existing" };
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error instanceof ProjectInitializationError ||
|
|
83
|
+
filesystemErrorCode(error) !== "ENOENT") {
|
|
84
|
+
if (error instanceof ProjectInitializationError) {
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
throw new ProjectInitializationError("WORKTREE_ALLOWLIST_WRITE_FAILED", `Unable to inspect the worktree allowlist target: ${path}`, [error instanceof Error ? error.message : String(error)]);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
writeFileSync(path, INITIAL_WORKTREE_ALLOWLIST_CONTENT, {
|
|
92
|
+
flag: "wx",
|
|
93
|
+
mode: 0o644,
|
|
94
|
+
});
|
|
95
|
+
return { path, status: "created" };
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (filesystemErrorCode(error) === "EEXIST") {
|
|
99
|
+
assertExistingWorktreeAllowlistIsRegular(path);
|
|
100
|
+
return { path, status: "existing" };
|
|
101
|
+
}
|
|
102
|
+
throw new ProjectInitializationError("WORKTREE_ALLOWLIST_WRITE_FAILED", `Unable to create the worktree allowlist: ${path}`, [error instanceof Error ? error.message : String(error)]);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function rollbackWorktreeAllowlistInitialization(initialization, originalError) {
|
|
106
|
+
if (initialization.status === "created") {
|
|
107
|
+
try {
|
|
108
|
+
const stats = lstatSync(initialization.path);
|
|
109
|
+
const content = readFileSync(initialization.path, "utf8");
|
|
110
|
+
if (stats.isSymbolicLink() ||
|
|
111
|
+
!stats.isFile() ||
|
|
112
|
+
content !== INITIAL_WORKTREE_ALLOWLIST_CONTENT) {
|
|
113
|
+
throw new Error("The newly created allowlist changed during initialization and was preserved.");
|
|
114
|
+
}
|
|
115
|
+
unlinkSync(initialization.path);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
if (filesystemErrorCode(error) !== "ENOENT") {
|
|
119
|
+
throw new ProjectInitializationError("WORKTREE_ALLOWLIST_ROLLBACK_FAILED", "Initialization failed and the automatically created worktree allowlist could not be rolled back safely.", [
|
|
120
|
+
`Original failure: ${originalError instanceof Error ? originalError.message : String(originalError)}`,
|
|
121
|
+
`Allowlist rollback failure: ${error instanceof Error ? error.message : String(error)}`,
|
|
122
|
+
`Preserved path: ${initialization.path}`,
|
|
123
|
+
]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
throw originalError;
|
|
128
|
+
}
|
|
46
129
|
function templateRoot() {
|
|
47
130
|
return fileURLToPath(new URL("../../templates/", import.meta.url));
|
|
48
131
|
}
|
|
@@ -229,7 +312,7 @@ export function verifyInitializedProject(targetDirectory, runner = runInitProces
|
|
|
229
312
|
const automationTests = runner(join(targetDirectory, "scripts/automation/tests/run-tests.sh"), [], { cwd: targetDirectory, timeoutMs: 300_000 });
|
|
230
313
|
const shadowRun = runner(join(targetDirectory, "scripts/automation/shadow-run.sh"), [], { cwd: targetDirectory, timeoutMs: 120_000 });
|
|
231
314
|
const checks = [
|
|
232
|
-
processCheck("automation-tests", "Automation transaction tests", automationTests, (stdout) => /(?:^|\n)1\.\.
|
|
315
|
+
processCheck("automation-tests", "Automation transaction tests", automationTests, (stdout) => /(?:^|\n)1\.\.42(?:\n|$)/.test(stdout)),
|
|
233
316
|
processCheck("shadow-run", "Read-only shadow run", shadowRun, shadowOutputIsSafe),
|
|
234
317
|
];
|
|
235
318
|
return {
|
|
@@ -269,6 +352,28 @@ function existingManifest(targetDirectory) {
|
|
|
269
352
|
throw error;
|
|
270
353
|
}
|
|
271
354
|
}
|
|
355
|
+
function optionsWithAutomaticGradleVerification(directory, options, runner) {
|
|
356
|
+
if (options.gradleVerification !== undefined) {
|
|
357
|
+
return options;
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
return {
|
|
361
|
+
...options,
|
|
362
|
+
gradleVerification: discoverGradleVerificationConfiguration(directory, runner, options.primaryModule === undefined
|
|
363
|
+
? {}
|
|
364
|
+
: { primaryModule: options.primaryModule }),
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
if (error instanceof GradleVerificationDiscoveryError) {
|
|
369
|
+
throw new ProjectInitializationError("GRADLE_DISCOVERY_FAILED", error.message, [
|
|
370
|
+
...error.details,
|
|
371
|
+
"Fix Gradle configuration or use --gradle-verification-config for an intentional project override.",
|
|
372
|
+
]);
|
|
373
|
+
}
|
|
374
|
+
throw error;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
272
377
|
function desiredFilesMatch(existing, planned) {
|
|
273
378
|
if (existing.files.length !== planned.files.length) {
|
|
274
379
|
return false;
|
|
@@ -313,7 +418,7 @@ function assertVerificationPassed(report) {
|
|
|
313
418
|
.flatMap((check) => [check.summary, ...check.details]));
|
|
314
419
|
}
|
|
315
420
|
}
|
|
316
|
-
function resultFromApplied(plan, applied, doctor, verification) {
|
|
421
|
+
function resultFromApplied(plan, applied, doctor, verification, worktreeAllowlist) {
|
|
317
422
|
return {
|
|
318
423
|
status: "installed",
|
|
319
424
|
targetDirectory: plan.targetDirectory,
|
|
@@ -324,6 +429,8 @@ function resultFromApplied(plan, applied, doctor, verification) {
|
|
|
324
429
|
managedFileCount: applied.manifest.files.length,
|
|
325
430
|
writtenFileCount: applied.writtenFileCount,
|
|
326
431
|
reusedFileCount: applied.reusedFileCount,
|
|
432
|
+
worktreeAllowlistPath: worktreeAllowlist.path,
|
|
433
|
+
worktreeAllowlistStatus: worktreeAllowlist.status,
|
|
327
434
|
manifest: applied.manifest,
|
|
328
435
|
doctor,
|
|
329
436
|
verification,
|
|
@@ -332,15 +439,23 @@ function resultFromApplied(plan, applied, doctor, verification) {
|
|
|
332
439
|
export function runProjectInitialization(directory, options = {}) {
|
|
333
440
|
const runner = options.processRunner ?? runInitProcess;
|
|
334
441
|
const doctor = doctorForInitialization(directory, options, runner);
|
|
335
|
-
const
|
|
442
|
+
const resolvedOptions = optionsWithAutomaticGradleVerification(directory, options, runner);
|
|
443
|
+
const plan = planProjectInitialization(directory, resolvedOptions);
|
|
336
444
|
const existing = existingManifest(plan.targetDirectory);
|
|
337
445
|
if (existing !== null) {
|
|
338
446
|
assertExistingInstallationIsCurrent(plan, existing);
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
447
|
+
const worktreeAllowlist = initializeWorktreeAllowlist(plan.targetDirectory);
|
|
448
|
+
let verification;
|
|
449
|
+
try {
|
|
450
|
+
verification = verifyInitializedProject(plan.targetDirectory, runner);
|
|
451
|
+
if (!verification.ok) {
|
|
452
|
+
throw new ProjectInitializationError("POST_INSTALL_VERIFICATION_FAILED", "The existing installation failed verification; no persistent file was changed.", verification.checks
|
|
453
|
+
.filter((check) => check.status === "fail")
|
|
454
|
+
.flatMap((check) => [check.summary, ...check.details]));
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
rollbackWorktreeAllowlistInitialization(worktreeAllowlist, error);
|
|
344
459
|
}
|
|
345
460
|
return {
|
|
346
461
|
status: "already-installed",
|
|
@@ -352,25 +467,34 @@ export function runProjectInitialization(directory, options = {}) {
|
|
|
352
467
|
managedFileCount: existing.files.length,
|
|
353
468
|
writtenFileCount: 0,
|
|
354
469
|
reusedFileCount: existing.files.length,
|
|
470
|
+
worktreeAllowlistPath: worktreeAllowlist.path,
|
|
471
|
+
worktreeAllowlistStatus: worktreeAllowlist.status,
|
|
355
472
|
manifest: existing,
|
|
356
473
|
doctor,
|
|
357
474
|
verification,
|
|
358
475
|
};
|
|
359
476
|
}
|
|
477
|
+
const worktreeAllowlist = initializeWorktreeAllowlist(plan.targetDirectory);
|
|
360
478
|
let verification = null;
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
479
|
+
let applied;
|
|
480
|
+
try {
|
|
481
|
+
applied = applyInstallationPlan(plan.installation, {
|
|
482
|
+
...(options.installedAt === undefined
|
|
483
|
+
? {}
|
|
484
|
+
: { installedAt: options.installedAt }),
|
|
485
|
+
verify: () => {
|
|
486
|
+
verification = verifyInitializedProject(plan.targetDirectory, runner);
|
|
487
|
+
assertVerificationPassed(verification);
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
catch (error) {
|
|
492
|
+
rollbackWorktreeAllowlistInitialization(worktreeAllowlist, error);
|
|
493
|
+
}
|
|
370
494
|
if (verification === null) {
|
|
371
495
|
throw new ProjectInitializationError("POST_INSTALL_VERIFICATION_FAILED", "Installation verification did not produce a report.");
|
|
372
496
|
}
|
|
373
|
-
return resultFromApplied(plan, applied, doctor, verification);
|
|
497
|
+
return resultFromApplied(plan, applied, doctor, verification, worktreeAllowlist);
|
|
374
498
|
}
|
|
375
499
|
export function formatProjectInitializationResult(result) {
|
|
376
500
|
const lines = [
|
|
@@ -383,6 +507,7 @@ export function formatProjectInitializationResult(result) {
|
|
|
383
507
|
`Managed files: ${String(result.managedFileCount)}`,
|
|
384
508
|
`Written files: ${String(result.writtenFileCount)}`,
|
|
385
509
|
`Reused files: ${String(result.reusedFileCount)}`,
|
|
510
|
+
`Worktree allowlist: ${result.worktreeAllowlistPath} (${result.worktreeAllowlistStatus})`,
|
|
386
511
|
`Manifest: ${result.manifestPath}`,
|
|
387
512
|
`Recovery backups: ${result.backupDirectory}`,
|
|
388
513
|
"Failure rollback: automatic until the manifest is marked installed",
|