agentplane 0.2.13 → 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/README.md +4 -0
- package/assets/AGENTS.md +17 -0
- 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 +3 -0
- package/dist/cli/run-cli/commands/init/ui.d.ts.map +1 -0
- package/dist/cli/run-cli/commands/init/ui.js +37 -0
- package/dist/cli/run-cli/commands/init/write-config.d.ts +16 -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 +6 -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 +3 -0
- package/dist/cli/run-cli/commands/init.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init.js +134 -13
- package/dist/commands/task/set-status.d.ts.map +1 -1
- package/dist/commands/task/set-status.js +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,6 +24,9 @@ agentplane init
|
|
|
24
24
|
agentplane quickstart
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
`agentplane init` is human-oriented: interactive onboarding includes workflow/backend selection,
|
|
28
|
+
execution profile selection (`conservative|balanced|aggressive`), approval toggles, and optional recipes.
|
|
29
|
+
|
|
27
30
|
Create your first task and run the workflow:
|
|
28
31
|
|
|
29
32
|
```bash
|
|
@@ -45,6 +48,7 @@ npx agentplane quickstart
|
|
|
45
48
|
- `AGENTS.md` is created if missing and defines the policy/guardrails.
|
|
46
49
|
- Built-in agent definitions are copied into `.agentplane/agents/`.
|
|
47
50
|
- Optional recipes can install additional agents when you run `agentplane recipes install ...`.
|
|
51
|
+
- `.agentplane/config.json` stores execution defaults under `execution` (profile, reasoning effort, tool budget, safety gates).
|
|
48
52
|
|
|
49
53
|
## Upgrade review reports
|
|
50
54
|
|
package/assets/AGENTS.md
CHANGED
|
@@ -107,6 +107,23 @@ Outside-repo includes (non-exhaustive):
|
|
|
107
107
|
- modifying keychains, ssh keys, credential stores
|
|
108
108
|
- any tool that mutates outside-repo state
|
|
109
109
|
|
|
110
|
+
## Execution Profile
|
|
111
|
+
|
|
112
|
+
`execution` settings in `.agentplane/config.json` define operational behavior defaults for agents:
|
|
113
|
+
|
|
114
|
+
- `profile`: `conservative` / `balanced` / `aggressive`
|
|
115
|
+
- `reasoning_effort`: `low` / `medium` / `high`
|
|
116
|
+
- `tool_budget`: `{ discovery, implementation, verification }`
|
|
117
|
+
- `stop_conditions`: conditions that force a stop/re-plan/escalation
|
|
118
|
+
- `handoff_conditions`: conditions that trigger handoff to another role
|
|
119
|
+
- `unsafe_actions_requiring_explicit_user_ok`: actions that require explicit user confirmation
|
|
120
|
+
|
|
121
|
+
Scope and precedence:
|
|
122
|
+
|
|
123
|
+
- These settings tune execution style only (autonomy, effort, budget, stop/handoff heuristics).
|
|
124
|
+
- They MUST NOT override role authority boundaries, source-of-truth order, approval gates, or hard invariants defined in this `AGENTS.md`.
|
|
125
|
+
- If `execution` config conflicts with policy, `AGENTS.md` policy wins.
|
|
126
|
+
|
|
110
127
|
## Framework Upgrade / Prompt Merge
|
|
111
128
|
|
|
112
129
|
`agentplane upgrade` is responsible for mechanical upgrades and safe merges. When an upgrade run indicates a potential semantic conflict (for example, both local and incoming changes exist relative to a baseline, or a baseline is missing but files differ), treat the result as requiring a meaning-level review.
|
|
@@ -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";
|
|
@@ -0,0 +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,CAY1C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAG5E"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
function useColor() {
|
|
2
|
+
return process.stdout.isTTY === true && (process.env.TERM ?? "dumb") !== "dumb";
|
|
3
|
+
}
|
|
4
|
+
function color(text, code) {
|
|
5
|
+
if (!useColor())
|
|
6
|
+
return text;
|
|
7
|
+
return `\u001B[${code}m${text}\u001B[0m`;
|
|
8
|
+
}
|
|
9
|
+
function padLine(line, width) {
|
|
10
|
+
if (line.length >= width)
|
|
11
|
+
return line;
|
|
12
|
+
return `${line}${" ".repeat(width - line.length)}`;
|
|
13
|
+
}
|
|
14
|
+
function box(lines) {
|
|
15
|
+
const width = Math.max(...lines.map((line) => line.length), 0);
|
|
16
|
+
const top = `┌${"─".repeat(width + 2)}┐`;
|
|
17
|
+
const body = lines.map((line) => `│ ${padLine(line, width)} │`);
|
|
18
|
+
const bottom = `└${"─".repeat(width + 2)}┘`;
|
|
19
|
+
return [top, ...body, bottom].join("\n");
|
|
20
|
+
}
|
|
21
|
+
export function renderInitWelcome() {
|
|
22
|
+
const logo = [
|
|
23
|
+
"░█▀█░█▀▀░█▀▀░█▀█░▀█▀░░░█░█▀█░█░░░█▀█░█▀█░█▀▀",
|
|
24
|
+
"░█▀█░█░█░█▀▀░█░█░░█░░▄▀░░█▀▀░█░░░█▀█░█░█░█▀▀",
|
|
25
|
+
"░▀░▀░▀▀▀░▀▀▀░▀░▀░░▀░░▀░░░▀░░░▀▀▀░▀░▀░▀░▀░▀▀▀",
|
|
26
|
+
].map((line) => color(line, "36"));
|
|
27
|
+
const subtitle = color("agent/plane", "36");
|
|
28
|
+
const intro = [
|
|
29
|
+
color("Bootstrap an agent-first workflow in this repository.", "1"),
|
|
30
|
+
"This interactive setup runs once; daily work is executed by agents.",
|
|
31
|
+
];
|
|
32
|
+
return `${logo.join("\n")}\n${subtitle}\n\n${box(intro)}\n\n`;
|
|
33
|
+
}
|
|
34
|
+
export function renderInitSection(title, description) {
|
|
35
|
+
const header = color(`[${title}]`, "33");
|
|
36
|
+
return `${header}\n${description}\n\n`;
|
|
37
|
+
}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type InitExecutionConfig = {
|
|
2
|
+
profile: "conservative" | "balanced" | "aggressive";
|
|
3
|
+
reasoning_effort: "low" | "medium" | "high";
|
|
4
|
+
tool_budget: {
|
|
5
|
+
discovery: number;
|
|
6
|
+
implementation: number;
|
|
7
|
+
verification: number;
|
|
8
|
+
};
|
|
9
|
+
stop_conditions: string[];
|
|
10
|
+
handoff_conditions: string[];
|
|
11
|
+
unsafe_actions_requiring_explicit_user_ok: string[];
|
|
12
|
+
};
|
|
13
|
+
export declare function ensureAgentplaneDirs(agentplaneDir: string, backend: "local" | "redmine"): Promise<void>;
|
|
2
14
|
export declare function writeInitConfig(opts: {
|
|
3
15
|
agentplaneDir: string;
|
|
4
16
|
gitRoot: string;
|
|
@@ -7,9 +19,10 @@ export declare function writeInitConfig(opts: {
|
|
|
7
19
|
requirePlanApproval: boolean;
|
|
8
20
|
requireNetworkApproval: boolean;
|
|
9
21
|
requireVerifyApproval: boolean;
|
|
22
|
+
execution: InitExecutionConfig;
|
|
10
23
|
}): Promise<void>;
|
|
11
24
|
export declare function writeBackendStubs(opts: {
|
|
12
|
-
|
|
13
|
-
|
|
25
|
+
backend: "local" | "redmine";
|
|
26
|
+
backendPath: string;
|
|
14
27
|
}): Promise<void>;
|
|
15
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,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();
|
|
@@ -17,6 +17,7 @@ export async function writeInitConfig(opts) {
|
|
|
17
17
|
setByDottedKey(rawConfig, "agents.approvals.require_plan", String(opts.requirePlanApproval));
|
|
18
18
|
setByDottedKey(rawConfig, "agents.approvals.require_network", String(opts.requireNetworkApproval));
|
|
19
19
|
setByDottedKey(rawConfig, "agents.approvals.require_verify", String(opts.requireVerifyApproval));
|
|
20
|
+
setByDottedKey(rawConfig, "execution", JSON.stringify(opts.execution));
|
|
20
21
|
await saveConfig(opts.agentplaneDir, rawConfig);
|
|
21
22
|
}
|
|
22
23
|
export async function writeBackendStubs(opts) {
|
|
@@ -29,13 +30,10 @@ export async function writeBackendStubs(opts) {
|
|
|
29
30
|
id: "redmine",
|
|
30
31
|
version: 1,
|
|
31
32
|
settings: {
|
|
32
|
-
url: "https://redmine.example",
|
|
33
|
-
api_key: "replace-me",
|
|
34
|
-
project_id: "replace-me",
|
|
35
33
|
owner_agent: "REDMINE",
|
|
36
34
|
custom_fields: { task_id: 1 },
|
|
37
35
|
},
|
|
38
36
|
};
|
|
39
|
-
|
|
40
|
-
await writeJsonStableIfChanged(opts.
|
|
37
|
+
const payload = opts.backend === "redmine" ? redmineBackendPayload : localBackendPayload;
|
|
38
|
+
await writeJsonStableIfChanged(opts.backendPath, payload);
|
|
41
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,4 +1,5 @@
|
|
|
1
1
|
import type { CommandHandler, CommandSpec } from "../../spec/spec.js";
|
|
2
|
+
type ExecutionProfile = "conservative" | "balanced" | "aggressive";
|
|
2
3
|
type InitFlags = {
|
|
3
4
|
ide?: "codex" | "cursor" | "windsurf";
|
|
4
5
|
workflow?: "direct" | "branch_pr";
|
|
@@ -8,6 +9,8 @@ type InitFlags = {
|
|
|
8
9
|
requirePlanApproval?: boolean;
|
|
9
10
|
requireNetworkApproval?: boolean;
|
|
10
11
|
requireVerifyApproval?: boolean;
|
|
12
|
+
executionProfile?: ExecutionProfile;
|
|
13
|
+
strictUnsafeConfirm?: boolean;
|
|
11
14
|
recipes?: string[];
|
|
12
15
|
force?: boolean;
|
|
13
16
|
backup?: boolean;
|
|
@@ -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"}
|
|
@@ -13,9 +13,76 @@ import { collectInitConflicts, handleInitConflicts } from "./init/conflicts.js";
|
|
|
13
13
|
import { ensureGitRoot } from "./init/git.js";
|
|
14
14
|
import { maybeSyncIde } from "./init/ide-sync.js";
|
|
15
15
|
import { maybeInstallBundledRecipes } from "./init/recipes.js";
|
|
16
|
-
import { ensureAgentplaneDirs, writeBackendStubs, writeInitConfig } from "./init/write-config.js";
|
|
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";
|
|
20
|
+
import { renderInitSection, renderInitWelcome } from "./init/ui.js";
|
|
21
|
+
function buildInitExecutionProfile(profile, opts) {
|
|
22
|
+
const shared = {
|
|
23
|
+
stop_conditions: [
|
|
24
|
+
"Missing required input blocks correctness.",
|
|
25
|
+
"Requested action expands scope or risk beyond approved plan.",
|
|
26
|
+
"Verification fails and remediation changes scope.",
|
|
27
|
+
],
|
|
28
|
+
handoff_conditions: [
|
|
29
|
+
"Role boundary reached (for example CODER -> TESTER/REVIEWER).",
|
|
30
|
+
"Task depends_on prerequisites are incomplete.",
|
|
31
|
+
"Specialized agent is required.",
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
const byProfile = {
|
|
35
|
+
conservative: {
|
|
36
|
+
profile: "conservative",
|
|
37
|
+
reasoning_effort: "high",
|
|
38
|
+
tool_budget: { discovery: 4, implementation: 8, verification: 8 },
|
|
39
|
+
...shared,
|
|
40
|
+
unsafe_actions_requiring_explicit_user_ok: [
|
|
41
|
+
"Destructive git history operations.",
|
|
42
|
+
"Outside-repo read/write.",
|
|
43
|
+
"Credential, keychain, or SSH material changes.",
|
|
44
|
+
"Network actions when approvals are enabled.",
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
balanced: {
|
|
48
|
+
profile: "balanced",
|
|
49
|
+
reasoning_effort: "medium",
|
|
50
|
+
tool_budget: { discovery: 6, implementation: 10, verification: 6 },
|
|
51
|
+
...shared,
|
|
52
|
+
unsafe_actions_requiring_explicit_user_ok: [
|
|
53
|
+
"Destructive git history operations.",
|
|
54
|
+
"Outside-repo read/write.",
|
|
55
|
+
"Credential, keychain, or SSH material changes.",
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
aggressive: {
|
|
59
|
+
profile: "aggressive",
|
|
60
|
+
reasoning_effort: "low",
|
|
61
|
+
tool_budget: { discovery: 10, implementation: 16, verification: 8 },
|
|
62
|
+
stop_conditions: [
|
|
63
|
+
"Requested action expands scope or risk beyond approved plan.",
|
|
64
|
+
"Verification fails and remediation changes scope.",
|
|
65
|
+
],
|
|
66
|
+
handoff_conditions: [
|
|
67
|
+
"Role boundary reached (for example CODER -> TESTER/REVIEWER).",
|
|
68
|
+
"Specialized agent is required.",
|
|
69
|
+
],
|
|
70
|
+
unsafe_actions_requiring_explicit_user_ok: [
|
|
71
|
+
"Destructive git history operations.",
|
|
72
|
+
"Outside-repo read/write.",
|
|
73
|
+
"Credential, keychain, or SSH material changes.",
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
const resolved = structuredClone(byProfile[profile]);
|
|
78
|
+
if (opts?.strictUnsafeConfirm === true) {
|
|
79
|
+
const extra = "Network actions when approvals are disabled.";
|
|
80
|
+
if (!resolved.unsafe_actions_requiring_explicit_user_ok.includes(extra)) {
|
|
81
|
+
resolved.unsafe_actions_requiring_explicit_user_ok.push(extra);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return resolved;
|
|
85
|
+
}
|
|
19
86
|
function parseBooleanValueForInit(flag, value) {
|
|
20
87
|
const normalized = value.trim().toLowerCase();
|
|
21
88
|
if (["1", "true", "yes", "y", "on"].includes(normalized))
|
|
@@ -90,6 +157,19 @@ export const initSpec = {
|
|
|
90
157
|
valueHint: "<true|false>",
|
|
91
158
|
description: "Require explicit approval before recording verification.",
|
|
92
159
|
},
|
|
160
|
+
{
|
|
161
|
+
kind: "string",
|
|
162
|
+
name: "execution-profile",
|
|
163
|
+
valueHint: "<conservative|balanced|aggressive>",
|
|
164
|
+
choices: ["conservative", "balanced", "aggressive"],
|
|
165
|
+
description: "Execution profile preset controlling autonomy, reasoning, and tool budgets.",
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
kind: "string",
|
|
169
|
+
name: "strict-unsafe-confirm",
|
|
170
|
+
valueHint: "<true|false>",
|
|
171
|
+
description: "Require strict explicit confirmations for additional unsafe actions.",
|
|
172
|
+
},
|
|
93
173
|
{
|
|
94
174
|
kind: "string",
|
|
95
175
|
name: "recipes",
|
|
@@ -165,6 +245,10 @@ export const initSpec = {
|
|
|
165
245
|
requireVerifyApproval: requireVerifyRaw === undefined
|
|
166
246
|
? undefined
|
|
167
247
|
: parseBooleanValueForInit("--require-verify-approval", requireVerifyRaw),
|
|
248
|
+
executionProfile: raw.opts["execution-profile"],
|
|
249
|
+
strictUnsafeConfirm: raw.opts["strict-unsafe-confirm"] === undefined
|
|
250
|
+
? undefined
|
|
251
|
+
: parseBooleanValueForInit("--strict-unsafe-confirm", String(raw.opts["strict-unsafe-confirm"])),
|
|
168
252
|
recipes: recipesRaw === undefined ? undefined : parseRecipesSelectionForInit(recipesRaw),
|
|
169
253
|
force: raw.opts.force === true,
|
|
170
254
|
backup: raw.opts.backup === true,
|
|
@@ -194,6 +278,8 @@ async function cmdInit(opts) {
|
|
|
194
278
|
requirePlanApproval: true,
|
|
195
279
|
requireNetworkApproval: true,
|
|
196
280
|
requireVerifyApproval: true,
|
|
281
|
+
executionProfile: "balanced",
|
|
282
|
+
strictUnsafeConfirm: false,
|
|
197
283
|
};
|
|
198
284
|
let ide = flags.ide ?? defaults.ide;
|
|
199
285
|
let workflow = flags.workflow ?? defaults.workflow;
|
|
@@ -203,6 +289,8 @@ async function cmdInit(opts) {
|
|
|
203
289
|
let requirePlanApproval = flags.requirePlanApproval ?? defaults.requirePlanApproval;
|
|
204
290
|
let requireNetworkApproval = flags.requireNetworkApproval ?? defaults.requireNetworkApproval;
|
|
205
291
|
let requireVerifyApproval = flags.requireVerifyApproval ?? defaults.requireVerifyApproval;
|
|
292
|
+
let executionProfile = flags.executionProfile ?? defaults.executionProfile;
|
|
293
|
+
let strictUnsafeConfirm = flags.strictUnsafeConfirm ?? defaults.strictUnsafeConfirm;
|
|
206
294
|
const isInteractive = process.stdin.isTTY && !flags.yes;
|
|
207
295
|
if (!process.stdin.isTTY &&
|
|
208
296
|
!flags.yes &&
|
|
@@ -218,30 +306,56 @@ async function cmdInit(opts) {
|
|
|
218
306
|
});
|
|
219
307
|
}
|
|
220
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
|
+
};
|
|
324
|
+
process.stdout.write(renderInitWelcome());
|
|
325
|
+
process.stdout.write(renderInitSection("Workflow", "Choose how branches/backends/approvals should be initialized for this repository."));
|
|
221
326
|
ide = flags.ide ?? defaults.ide;
|
|
222
327
|
if (!flags.workflow) {
|
|
223
|
-
const choice = await
|
|
328
|
+
const choice = await askChoice("Workflow mode", ["direct", "branch_pr"], workflow);
|
|
224
329
|
workflow = choice === "branch_pr" ? "branch_pr" : "direct";
|
|
225
330
|
}
|
|
226
331
|
if (!flags.backend) {
|
|
227
|
-
const choice = await
|
|
332
|
+
const choice = await askChoice("Task backend", ["local", "redmine"], backend);
|
|
228
333
|
backend = choice === "redmine" ? "redmine" : "local";
|
|
229
334
|
}
|
|
230
335
|
if (flags.hooks === undefined) {
|
|
231
|
-
hooks = await
|
|
336
|
+
hooks = await askYesNo("Install managed git hooks now?", hooks);
|
|
337
|
+
}
|
|
338
|
+
process.stdout.write(renderInitSection("Execution Profile", "Set default autonomy/effort for agents. You can change this later in config."));
|
|
339
|
+
if (!flags.executionProfile) {
|
|
340
|
+
executionProfile = (await askChoice("Execution profile", ["conservative", "balanced", "aggressive"], executionProfile));
|
|
232
341
|
}
|
|
342
|
+
if (flags.strictUnsafeConfirm === undefined) {
|
|
343
|
+
strictUnsafeConfirm = await askYesNo("Require strict explicit confirmation for extra unsafe actions?", strictUnsafeConfirm);
|
|
344
|
+
}
|
|
345
|
+
process.stdout.write(renderInitSection("Approvals", "Control whether plan/network/verification actions require explicit approval by default."));
|
|
233
346
|
if (flags.requirePlanApproval === undefined) {
|
|
234
|
-
requirePlanApproval = await
|
|
347
|
+
requirePlanApproval = await askYesNo("Require plan approval before work starts?", requirePlanApproval);
|
|
235
348
|
}
|
|
236
349
|
if (flags.requireNetworkApproval === undefined) {
|
|
237
|
-
requireNetworkApproval = await
|
|
350
|
+
requireNetworkApproval = await askYesNo("Require explicit approval for network actions?", requireNetworkApproval);
|
|
238
351
|
}
|
|
239
352
|
if (flags.requireVerifyApproval === undefined) {
|
|
240
|
-
requireVerifyApproval = await
|
|
353
|
+
requireVerifyApproval = await askYesNo("Require explicit approval before recording verification?", requireVerifyApproval);
|
|
241
354
|
}
|
|
355
|
+
process.stdout.write(renderInitSection("Recipes", "Optional: install recipe packs now (comma-separated IDs) or choose none."));
|
|
242
356
|
if (!flags.recipes) {
|
|
243
357
|
process.stdout.write(`${renderBundledRecipesHint()}\n`);
|
|
244
|
-
const answer = await
|
|
358
|
+
const answer = await askInput("Install optional recipes (comma separated, or none): ");
|
|
245
359
|
recipes = answer
|
|
246
360
|
? answer
|
|
247
361
|
.split(",")
|
|
@@ -259,6 +373,8 @@ async function cmdInit(opts) {
|
|
|
259
373
|
requirePlanApproval = flags.requirePlanApproval ?? defaults.requirePlanApproval;
|
|
260
374
|
requireNetworkApproval = flags.requireNetworkApproval ?? defaults.requireNetworkApproval;
|
|
261
375
|
requireVerifyApproval = flags.requireVerifyApproval ?? defaults.requireVerifyApproval;
|
|
376
|
+
executionProfile = flags.executionProfile ?? defaults.executionProfile;
|
|
377
|
+
strictUnsafeConfirm = flags.strictUnsafeConfirm ?? defaults.strictUnsafeConfirm;
|
|
262
378
|
}
|
|
263
379
|
validateBundledRecipesSelection(recipes);
|
|
264
380
|
try {
|
|
@@ -283,10 +399,9 @@ async function cmdInit(opts) {
|
|
|
283
399
|
path.join(resolved.agentplaneDir, "agents"),
|
|
284
400
|
path.join(resolved.agentplaneDir, "cache"),
|
|
285
401
|
path.join(resolved.agentplaneDir, "backends"),
|
|
286
|
-
path.join(resolved.agentplaneDir, "backends",
|
|
287
|
-
path.join(resolved.agentplaneDir, "backends", "redmine"),
|
|
402
|
+
path.join(resolved.agentplaneDir, "backends", backend),
|
|
288
403
|
];
|
|
289
|
-
const initFiles = [configPath,
|
|
404
|
+
const initFiles = [configPath, backendPath];
|
|
290
405
|
const conflicts = await collectInitConflicts({ initDirs, initFiles });
|
|
291
406
|
await handleInitConflicts({
|
|
292
407
|
gitRoot: resolved.gitRoot,
|
|
@@ -294,7 +409,8 @@ async function cmdInit(opts) {
|
|
|
294
409
|
backup: flags.backup === true,
|
|
295
410
|
force: flags.force === true,
|
|
296
411
|
});
|
|
297
|
-
await ensureAgentplaneDirs(resolved.agentplaneDir);
|
|
412
|
+
await ensureAgentplaneDirs(resolved.agentplaneDir, backend);
|
|
413
|
+
const execution = buildInitExecutionProfile(executionProfile, { strictUnsafeConfirm });
|
|
298
414
|
await writeInitConfig({
|
|
299
415
|
agentplaneDir: resolved.agentplaneDir,
|
|
300
416
|
gitRoot: resolved.gitRoot,
|
|
@@ -303,8 +419,12 @@ async function cmdInit(opts) {
|
|
|
303
419
|
requirePlanApproval,
|
|
304
420
|
requireNetworkApproval,
|
|
305
421
|
requireVerifyApproval,
|
|
422
|
+
execution,
|
|
306
423
|
});
|
|
307
|
-
await writeBackendStubs({
|
|
424
|
+
await writeBackendStubs({ backend, backendPath });
|
|
425
|
+
if (backend === "redmine") {
|
|
426
|
+
await ensureInitRedmineEnvTemplate({ gitRoot: resolved.gitRoot });
|
|
427
|
+
}
|
|
308
428
|
const { installPaths } = await ensureAgentsFiles({
|
|
309
429
|
gitRoot: resolved.gitRoot,
|
|
310
430
|
agentplaneDir: resolved.agentplaneDir,
|
|
@@ -316,6 +436,7 @@ async function cmdInit(opts) {
|
|
|
316
436
|
gitRoot: resolved.gitRoot,
|
|
317
437
|
includeAgentPromptFiles: flags.gitignoreAgents === true,
|
|
318
438
|
});
|
|
439
|
+
installPaths.push(".gitignore");
|
|
319
440
|
if (flags.gitignoreAgents) {
|
|
320
441
|
await setPinnedBaseBranch({
|
|
321
442
|
cwd: resolved.gitRoot,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAcnC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"set-status.d.ts","sourceRoot":"","sources":["../../../src/commands/task/set-status.ts"],"names":[],"mappings":"AAOA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAcnC,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiKlB"}
|
|
@@ -26,6 +26,16 @@ export async function cmdTaskSetStatus(opts) {
|
|
|
26
26
|
const ctx = opts.ctx ??
|
|
27
27
|
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
28
28
|
const config = ctx.config;
|
|
29
|
+
const executionProfile = String(config.execution?.profile ?? "balanced").toLowerCase();
|
|
30
|
+
if (opts.force &&
|
|
31
|
+
executionProfile === "conservative" &&
|
|
32
|
+
process.env.AGENTPLANE_EXECUTION_FORCE_OK !== "1") {
|
|
33
|
+
throw new CliError({
|
|
34
|
+
exitCode: 2,
|
|
35
|
+
code: "E_USAGE",
|
|
36
|
+
message: "Conservative execution profile blocks --force by default. Set AGENTPLANE_EXECUTION_FORCE_OK=1 to override.",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
29
39
|
const resolved = ctx.resolvedProject;
|
|
30
40
|
const useStore = backendIsLocalFileBackend(ctx);
|
|
31
41
|
const store = useStore ? getTaskStore(ctx) : null;
|