agentplane 0.2.14 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine-backend.js +9 -2
- package/dist/backends/task-backend/shared/errors.js +1 -1
- package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/ui.js +6 -7
- package/dist/cli/run-cli/commands/init/write-config.d.ts +3 -3
- package/dist/cli/run-cli/commands/init/write-config.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-config.js +5 -8
- package/dist/cli/run-cli/commands/init/write-env.d.ts +4 -0
- package/dist/cli/run-cli/commands/init/write-env.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/init/write-env.js +89 -0
- package/dist/cli/run-cli/commands/init/write-gitignore.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-gitignore.js +1 -0
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +33 -14
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redmine-backend.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/redmine-backend.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA0BvD,OAAO,EAkBL,KAAK,WAAW,EAChB,KAAK,QAAQ,EAEd,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,cAAe,YAAW,WAAW;IAChD,EAAE,SAAa;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,UAAU,uCAA8C;IACxD,aAAa,sBAA6B;gBAE9B,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;KAAE;
|
|
1
|
+
{"version":3,"file":"redmine-backend.d.ts","sourceRoot":"","sources":["../../../src/backends/task-backend/redmine-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,8 +37,15 @@ export class RedmineBackend {
|
|
|
37
37
|
this.batchPause = typeof settings.batch_pause === "number" ? settings.batch_pause : 0.5;
|
|
38
38
|
this.ownerAgent = firstNonEmptyString(envOwner, settings.owner_agent, "REDMINE");
|
|
39
39
|
this.cache = opts.cache ?? null;
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const missingEnvKeys = [];
|
|
41
|
+
if (!this.baseUrl)
|
|
42
|
+
missingEnvKeys.push("AGENTPLANE_REDMINE_URL");
|
|
43
|
+
if (!this.apiKey)
|
|
44
|
+
missingEnvKeys.push("AGENTPLANE_REDMINE_API_KEY");
|
|
45
|
+
if (!this.projectId)
|
|
46
|
+
missingEnvKeys.push("AGENTPLANE_REDMINE_PROJECT_ID");
|
|
47
|
+
if (missingEnvKeys.length > 0) {
|
|
48
|
+
throw new BackendError(redmineConfigMissingMessage(missingEnvKeys.join(", ")), "E_BACKEND");
|
|
42
49
|
}
|
|
43
50
|
if (!this.customFields?.task_id) {
|
|
44
51
|
throw new BackendError(redmineConfigMissingMessage("custom_fields.task_id"), "E_BACKEND");
|
|
@@ -11,7 +11,7 @@ export class RedmineUnavailable extends BackendError {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
export function redmineConfigMissingMessage(detail) {
|
|
14
|
-
return `Missing required Redmine
|
|
14
|
+
return `Missing required Redmine configuration. Set ${detail} in environment variables (for example via .env).`;
|
|
15
15
|
}
|
|
16
16
|
export function redmineIssueIdMissingMessage() {
|
|
17
17
|
return "Missing Redmine issue id for task";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/ui.ts"],"names":[],"mappings":"AAsBA,wBAAgB,iBAAiB,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/ui.ts"],"names":[],"mappings":"AAsBA,wBAAgB,iBAAiB,IAAI,MAAM,CAY1C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAG5E"}
|
|
@@ -20,19 +20,18 @@ function box(lines) {
|
|
|
20
20
|
}
|
|
21
21
|
export function renderInitWelcome() {
|
|
22
22
|
const logo = [
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
String.raw `/_/ |_|\__/ /___//_/|_/\___/ `,
|
|
27
|
-
" agent/plane ",
|
|
23
|
+
"░█▀█░█▀▀░█▀▀░█▀█░▀█▀░░░█░█▀█░█░░░█▀█░█▀█░█▀▀",
|
|
24
|
+
"░█▀█░█░█░█▀▀░█░█░░█░░▄▀░░█▀▀░█░░░█▀█░█░█░█▀▀",
|
|
25
|
+
"░▀░▀░▀▀▀░▀▀▀░▀░▀░░▀░░▀░░░▀░░░▀▀▀░▀░▀░▀░▀░▀▀▀",
|
|
28
26
|
].map((line) => color(line, "36"));
|
|
27
|
+
const subtitle = color("agent/plane", "36");
|
|
29
28
|
const intro = [
|
|
30
29
|
color("Bootstrap an agent-first workflow in this repository.", "1"),
|
|
31
30
|
"This interactive setup runs once; daily work is executed by agents.",
|
|
32
31
|
];
|
|
33
|
-
return `${logo.join("\n")}\n\n${box(intro)}\n`;
|
|
32
|
+
return `${logo.join("\n")}\n${subtitle}\n\n${box(intro)}\n\n`;
|
|
34
33
|
}
|
|
35
34
|
export function renderInitSection(title, description) {
|
|
36
35
|
const header = color(`[${title}]`, "33");
|
|
37
|
-
return `${header}\n${description}\n`;
|
|
36
|
+
return `${header}\n${description}\n\n`;
|
|
38
37
|
}
|
|
@@ -10,7 +10,7 @@ export type InitExecutionConfig = {
|
|
|
10
10
|
handoff_conditions: string[];
|
|
11
11
|
unsafe_actions_requiring_explicit_user_ok: string[];
|
|
12
12
|
};
|
|
13
|
-
export declare function ensureAgentplaneDirs(agentplaneDir: string): Promise<void>;
|
|
13
|
+
export declare function ensureAgentplaneDirs(agentplaneDir: string, backend: "local" | "redmine"): Promise<void>;
|
|
14
14
|
export declare function writeInitConfig(opts: {
|
|
15
15
|
agentplaneDir: string;
|
|
16
16
|
gitRoot: string;
|
|
@@ -22,7 +22,7 @@ export declare function writeInitConfig(opts: {
|
|
|
22
22
|
execution: InitExecutionConfig;
|
|
23
23
|
}): Promise<void>;
|
|
24
24
|
export declare function writeBackendStubs(opts: {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
backend: "local" | "redmine";
|
|
26
|
+
backendPath: string;
|
|
27
27
|
}): Promise<void>;
|
|
28
28
|
//# sourceMappingURL=write-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-config.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-config.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;IACpD,gBAAgB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5C,WAAW,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,yCAAyC,EAAE,MAAM,EAAE,CAAC;CACrD,CAAC;AAEF,wBAAsB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"write-config.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-config.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;IACpD,gBAAgB,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5C,WAAW,EAAE;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,yCAAyC,EAAE,MAAM,EAAE,CAAC;CACrD,CAAC;AAEF,wBAAsB,oBAAoB,CACxC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,GAAG,SAAS,GAC3B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,SAAS,EAAE,mBAAmB,CAAC;CAChC,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhB;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhB"}
|
|
@@ -2,13 +2,13 @@ import { mkdir } from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { defaultConfig, saveConfig, setByDottedKey } from "@agentplaneorg/core";
|
|
4
4
|
import { writeJsonStableIfChanged } from "../../../../shared/write-if-changed.js";
|
|
5
|
-
export async function ensureAgentplaneDirs(agentplaneDir) {
|
|
5
|
+
export async function ensureAgentplaneDirs(agentplaneDir, backend) {
|
|
6
6
|
await mkdir(agentplaneDir, { recursive: true });
|
|
7
7
|
await mkdir(path.join(agentplaneDir, "tasks"), { recursive: true });
|
|
8
8
|
await mkdir(path.join(agentplaneDir, "agents"), { recursive: true });
|
|
9
9
|
await mkdir(path.join(agentplaneDir, "cache"), { recursive: true });
|
|
10
|
-
await mkdir(path.join(agentplaneDir, "backends"
|
|
11
|
-
await mkdir(path.join(agentplaneDir, "backends",
|
|
10
|
+
await mkdir(path.join(agentplaneDir, "backends"), { recursive: true });
|
|
11
|
+
await mkdir(path.join(agentplaneDir, "backends", backend), { recursive: true });
|
|
12
12
|
}
|
|
13
13
|
export async function writeInitConfig(opts) {
|
|
14
14
|
const rawConfig = defaultConfig();
|
|
@@ -30,13 +30,10 @@ export async function writeBackendStubs(opts) {
|
|
|
30
30
|
id: "redmine",
|
|
31
31
|
version: 1,
|
|
32
32
|
settings: {
|
|
33
|
-
url: "https://redmine.example",
|
|
34
|
-
api_key: "replace-me",
|
|
35
|
-
project_id: "replace-me",
|
|
36
33
|
owner_agent: "REDMINE",
|
|
37
34
|
custom_fields: { task_id: 1 },
|
|
38
35
|
},
|
|
39
36
|
};
|
|
40
|
-
|
|
41
|
-
await writeJsonStableIfChanged(opts.
|
|
37
|
+
const payload = opts.backend === "redmine" ? redmineBackendPayload : localBackendPayload;
|
|
38
|
+
await writeJsonStableIfChanged(opts.backendPath, payload);
|
|
42
39
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-env.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-env.ts"],"names":[],"mappings":"AAkEA,wBAAsB,4BAA4B,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC3F"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { writeTextIfChanged } from "../../../../shared/write-if-changed.js";
|
|
4
|
+
const REDMINE_ENV_TEMPLATE = [
|
|
5
|
+
{
|
|
6
|
+
key: "AGENTPLANE_REDMINE_URL",
|
|
7
|
+
value: "https://redmine.example",
|
|
8
|
+
comment: "Redmine base URL.",
|
|
9
|
+
required: true,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
key: "AGENTPLANE_REDMINE_API_KEY",
|
|
13
|
+
value: "replace-me",
|
|
14
|
+
comment: "Redmine API key.",
|
|
15
|
+
required: true,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
key: "AGENTPLANE_REDMINE_PROJECT_ID",
|
|
19
|
+
value: "replace-me",
|
|
20
|
+
comment: "Project identifier (numeric ID or project slug).",
|
|
21
|
+
required: true,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
key: "AGENTPLANE_REDMINE_OWNER_AGENT",
|
|
25
|
+
value: "REDMINE",
|
|
26
|
+
comment: "Optional default owner agent.",
|
|
27
|
+
required: false,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
key: "AGENTPLANE_REDMINE_ASSIGNEE_ID",
|
|
31
|
+
value: "",
|
|
32
|
+
comment: "Optional assignee numeric ID.",
|
|
33
|
+
required: false,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
async function readTextIfExists(filePath) {
|
|
37
|
+
try {
|
|
38
|
+
return await readFile(filePath, "utf8");
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
const code = err?.code;
|
|
42
|
+
if (code === "ENOENT")
|
|
43
|
+
return null;
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function collectDefinedEnvKeys(dotEnvText) {
|
|
48
|
+
const keys = new Set();
|
|
49
|
+
for (const line of dotEnvText.split(/\r?\n/u)) {
|
|
50
|
+
const trimmed = line.trim();
|
|
51
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
52
|
+
continue;
|
|
53
|
+
const match = /^([A-Za-z_][A-Za-z0-9_]*)\s*=/u.exec(trimmed);
|
|
54
|
+
if (match?.[1])
|
|
55
|
+
keys.add(match[1]);
|
|
56
|
+
}
|
|
57
|
+
return keys;
|
|
58
|
+
}
|
|
59
|
+
export async function ensureInitRedmineEnvTemplate(opts) {
|
|
60
|
+
const dotEnvPath = path.join(opts.gitRoot, ".env");
|
|
61
|
+
const existing = (await readTextIfExists(dotEnvPath)) ?? "";
|
|
62
|
+
const definedKeys = collectDefinedEnvKeys(existing);
|
|
63
|
+
const missing = REDMINE_ENV_TEMPLATE.filter((entry) => !definedKeys.has(entry.key));
|
|
64
|
+
if (missing.length === 0)
|
|
65
|
+
return;
|
|
66
|
+
const required = missing.filter((item) => item.required);
|
|
67
|
+
const optional = missing.filter((item) => !item.required);
|
|
68
|
+
const requiredLines = required.flatMap((entry) => [
|
|
69
|
+
`# ${entry.comment}`,
|
|
70
|
+
`${entry.key}=${entry.value}`,
|
|
71
|
+
]);
|
|
72
|
+
const optionalLines = optional.length === 0
|
|
73
|
+
? []
|
|
74
|
+
: [
|
|
75
|
+
"",
|
|
76
|
+
"# Optional values:",
|
|
77
|
+
...optional.flatMap((entry) => [`# ${entry.comment}`, `${entry.key}=${entry.value}`]),
|
|
78
|
+
];
|
|
79
|
+
const lines = [
|
|
80
|
+
"# agentplane: redmine backend configuration",
|
|
81
|
+
"# Required values:",
|
|
82
|
+
...requiredLines,
|
|
83
|
+
...optionalLines,
|
|
84
|
+
];
|
|
85
|
+
const block = `${lines.join("\n")}\n`;
|
|
86
|
+
const prefix = existing.length > 0 && !existing.endsWith("\n") ? "\n\n" : existing.length > 0 ? "\n" : "";
|
|
87
|
+
const next = `${existing}${prefix}${block}`;
|
|
88
|
+
await writeTextIfChanged(dotEnvPath, next);
|
|
89
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-gitignore.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-gitignore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"write-gitignore.d.ts","sourceRoot":"","sources":["../../../../../src/cli/run-cli/commands/init/write-gitignore.ts"],"names":[],"mappings":"AAiCA,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB,EAAE,OAAO,CAAC;CAClC,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/init.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../src/cli/run-cli/commands/init.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAsBtE,KAAK,gBAAgB,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAuEnE,KAAK,SAAS,GAAG;IACf,GAAG,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtC,QAAQ,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IAClC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAsBF,KAAK,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5D,eAAO,MAAM,QAAQ,EAAE,WAAW,CAAC,UAAU,CA2K5C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,cAAc,CAAC,UAAU,CACmB,CAAC"}
|
|
@@ -16,6 +16,7 @@ import { maybeInstallBundledRecipes } from "./init/recipes.js";
|
|
|
16
16
|
import { ensureAgentplaneDirs, writeBackendStubs, writeInitConfig, } from "./init/write-config.js";
|
|
17
17
|
import { ensureAgentsFiles } from "./init/write-agents.js";
|
|
18
18
|
import { ensureInitGitignore } from "./init/write-gitignore.js";
|
|
19
|
+
import { ensureInitRedmineEnvTemplate } from "./init/write-env.js";
|
|
19
20
|
import { renderInitSection, renderInitWelcome } from "./init/ui.js";
|
|
20
21
|
function buildInitExecutionProfile(profile, opts) {
|
|
21
22
|
const shared = {
|
|
@@ -305,41 +306,56 @@ async function cmdInit(opts) {
|
|
|
305
306
|
});
|
|
306
307
|
}
|
|
307
308
|
if (isInteractive) {
|
|
309
|
+
const askChoice = async (label, choices, defaultValue) => {
|
|
310
|
+
const result = await promptChoice(`\n${label}`, choices, defaultValue);
|
|
311
|
+
process.stdout.write("\n");
|
|
312
|
+
return result;
|
|
313
|
+
};
|
|
314
|
+
const askYesNo = async (label, defaultValue) => {
|
|
315
|
+
const result = await promptYesNo(`\n${label}`, defaultValue);
|
|
316
|
+
process.stdout.write("\n");
|
|
317
|
+
return result;
|
|
318
|
+
};
|
|
319
|
+
const askInput = async (label) => {
|
|
320
|
+
const result = await promptInput(`\n${label}`);
|
|
321
|
+
process.stdout.write("\n");
|
|
322
|
+
return result;
|
|
323
|
+
};
|
|
308
324
|
process.stdout.write(renderInitWelcome());
|
|
309
325
|
process.stdout.write(renderInitSection("Workflow", "Choose how branches/backends/approvals should be initialized for this repository."));
|
|
310
326
|
ide = flags.ide ?? defaults.ide;
|
|
311
327
|
if (!flags.workflow) {
|
|
312
|
-
const choice = await
|
|
328
|
+
const choice = await askChoice("Workflow mode", ["direct", "branch_pr"], workflow);
|
|
313
329
|
workflow = choice === "branch_pr" ? "branch_pr" : "direct";
|
|
314
330
|
}
|
|
315
331
|
if (!flags.backend) {
|
|
316
|
-
const choice = await
|
|
332
|
+
const choice = await askChoice("Task backend", ["local", "redmine"], backend);
|
|
317
333
|
backend = choice === "redmine" ? "redmine" : "local";
|
|
318
334
|
}
|
|
319
335
|
if (flags.hooks === undefined) {
|
|
320
|
-
hooks = await
|
|
336
|
+
hooks = await askYesNo("Install managed git hooks now?", hooks);
|
|
321
337
|
}
|
|
322
338
|
process.stdout.write(renderInitSection("Execution Profile", "Set default autonomy/effort for agents. You can change this later in config."));
|
|
323
339
|
if (!flags.executionProfile) {
|
|
324
|
-
executionProfile = (await
|
|
340
|
+
executionProfile = (await askChoice("Execution profile", ["conservative", "balanced", "aggressive"], executionProfile));
|
|
325
341
|
}
|
|
326
342
|
if (flags.strictUnsafeConfirm === undefined) {
|
|
327
|
-
strictUnsafeConfirm = await
|
|
343
|
+
strictUnsafeConfirm = await askYesNo("Require strict explicit confirmation for extra unsafe actions?", strictUnsafeConfirm);
|
|
328
344
|
}
|
|
329
345
|
process.stdout.write(renderInitSection("Approvals", "Control whether plan/network/verification actions require explicit approval by default."));
|
|
330
346
|
if (flags.requirePlanApproval === undefined) {
|
|
331
|
-
requirePlanApproval = await
|
|
347
|
+
requirePlanApproval = await askYesNo("Require plan approval before work starts?", requirePlanApproval);
|
|
332
348
|
}
|
|
333
349
|
if (flags.requireNetworkApproval === undefined) {
|
|
334
|
-
requireNetworkApproval = await
|
|
350
|
+
requireNetworkApproval = await askYesNo("Require explicit approval for network actions?", requireNetworkApproval);
|
|
335
351
|
}
|
|
336
352
|
if (flags.requireVerifyApproval === undefined) {
|
|
337
|
-
requireVerifyApproval = await
|
|
353
|
+
requireVerifyApproval = await askYesNo("Require explicit approval before recording verification?", requireVerifyApproval);
|
|
338
354
|
}
|
|
339
355
|
process.stdout.write(renderInitSection("Recipes", "Optional: install recipe packs now (comma-separated IDs) or choose none."));
|
|
340
356
|
if (!flags.recipes) {
|
|
341
357
|
process.stdout.write(`${renderBundledRecipesHint()}\n`);
|
|
342
|
-
const answer = await
|
|
358
|
+
const answer = await askInput("Install optional recipes (comma separated, or none): ");
|
|
343
359
|
recipes = answer
|
|
344
360
|
? answer
|
|
345
361
|
.split(",")
|
|
@@ -383,10 +399,9 @@ async function cmdInit(opts) {
|
|
|
383
399
|
path.join(resolved.agentplaneDir, "agents"),
|
|
384
400
|
path.join(resolved.agentplaneDir, "cache"),
|
|
385
401
|
path.join(resolved.agentplaneDir, "backends"),
|
|
386
|
-
path.join(resolved.agentplaneDir, "backends",
|
|
387
|
-
path.join(resolved.agentplaneDir, "backends", "redmine"),
|
|
402
|
+
path.join(resolved.agentplaneDir, "backends", backend),
|
|
388
403
|
];
|
|
389
|
-
const initFiles = [configPath,
|
|
404
|
+
const initFiles = [configPath, backendPath];
|
|
390
405
|
const conflicts = await collectInitConflicts({ initDirs, initFiles });
|
|
391
406
|
await handleInitConflicts({
|
|
392
407
|
gitRoot: resolved.gitRoot,
|
|
@@ -394,7 +409,7 @@ async function cmdInit(opts) {
|
|
|
394
409
|
backup: flags.backup === true,
|
|
395
410
|
force: flags.force === true,
|
|
396
411
|
});
|
|
397
|
-
await ensureAgentplaneDirs(resolved.agentplaneDir);
|
|
412
|
+
await ensureAgentplaneDirs(resolved.agentplaneDir, backend);
|
|
398
413
|
const execution = buildInitExecutionProfile(executionProfile, { strictUnsafeConfirm });
|
|
399
414
|
await writeInitConfig({
|
|
400
415
|
agentplaneDir: resolved.agentplaneDir,
|
|
@@ -406,7 +421,10 @@ async function cmdInit(opts) {
|
|
|
406
421
|
requireVerifyApproval,
|
|
407
422
|
execution,
|
|
408
423
|
});
|
|
409
|
-
await writeBackendStubs({
|
|
424
|
+
await writeBackendStubs({ backend, backendPath });
|
|
425
|
+
if (backend === "redmine") {
|
|
426
|
+
await ensureInitRedmineEnvTemplate({ gitRoot: resolved.gitRoot });
|
|
427
|
+
}
|
|
410
428
|
const { installPaths } = await ensureAgentsFiles({
|
|
411
429
|
gitRoot: resolved.gitRoot,
|
|
412
430
|
agentplaneDir: resolved.agentplaneDir,
|
|
@@ -418,6 +436,7 @@ async function cmdInit(opts) {
|
|
|
418
436
|
gitRoot: resolved.gitRoot,
|
|
419
437
|
includeAgentPromptFiles: flags.gitignoreAgents === true,
|
|
420
438
|
});
|
|
439
|
+
installPaths.push(".gitignore");
|
|
421
440
|
if (flags.gitignoreAgents) {
|
|
422
441
|
await setPinnedBaseBranch({
|
|
423
442
|
cwd: resolved.gitRoot,
|