agentplane 0.3.6 → 0.3.7
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/.build-manifest.json +106 -96
- package/dist/adapters/task-backend/task-backend-adapter.d.ts +2 -2
- package/dist/adapters/task-backend/task-backend-adapter.d.ts.map +1 -1
- package/dist/adapters/task-backend/task-backend-adapter.js +2 -2
- package/dist/backends/task-backend/local-backend.d.ts +7 -5
- package/dist/backends/task-backend/local-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/local-backend.js +79 -7
- package/dist/backends/task-backend/redmine/env.d.ts +1 -1
- package/dist/backends/task-backend/redmine/env.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine/env.js +3 -0
- package/dist/backends/task-backend/redmine/inspect.d.ts +11 -0
- package/dist/backends/task-backend/redmine/inspect.d.ts.map +1 -0
- package/dist/backends/task-backend/redmine/inspect.js +75 -0
- package/dist/backends/task-backend/redmine/mapping.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine/mapping.js +21 -2
- package/dist/backends/task-backend/redmine/state.d.ts +17 -0
- package/dist/backends/task-backend/redmine/state.d.ts.map +1 -0
- package/dist/backends/task-backend/redmine/state.js +95 -0
- package/dist/backends/task-backend/redmine-backend.d.ts +10 -16
- package/dist/backends/task-backend/redmine-backend.d.ts.map +1 -1
- package/dist/backends/task-backend/redmine-backend.js +205 -15
- package/dist/backends/task-backend/shared/constants.d.ts +1 -1
- package/dist/backends/task-backend/shared/constants.js +1 -1
- package/dist/backends/task-backend/shared/record.d.ts.map +1 -1
- package/dist/backends/task-backend/shared/record.js +20 -1
- package/dist/backends/task-backend/shared/types.d.ts +42 -4
- package/dist/backends/task-backend/shared/types.d.ts.map +1 -1
- package/dist/backends/task-backend/shared.d.ts +1 -1
- package/dist/backends/task-backend/shared.d.ts.map +1 -1
- package/dist/backends/task-backend.d.ts +1 -1
- package/dist/backends/task-backend.d.ts.map +1 -1
- package/dist/backends/task-index.d.ts.map +1 -1
- package/dist/backends/task-index.js +1 -0
- package/dist/cli/run-cli/command-catalog/project.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog/project.d.ts.map +1 -1
- package/dist/cli/run-cli/command-catalog/project.js +3 -1
- package/dist/cli/run-cli/command-catalog.d.ts +1 -1
- package/dist/cli/run-cli/command-catalog.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-env.d.ts.map +1 -1
- package/dist/cli/run-cli/commands/init/write-env.js +12 -0
- package/dist/cli/run-cli.test-helpers.d.ts.map +1 -1
- package/dist/cli/run-cli.test-helpers.js +2 -0
- package/dist/commands/backend/sync.command.d.ts +5 -1
- package/dist/commands/backend/sync.command.d.ts.map +1 -1
- package/dist/commands/backend/sync.command.js +67 -3
- package/dist/commands/backend.d.ts +22 -0
- package/dist/commands/backend.d.ts.map +1 -1
- package/dist/commands/backend.js +110 -1
- package/dist/commands/commit.spec.d.ts.map +1 -1
- package/dist/commands/commit.spec.js +30 -6
- package/dist/commands/doctor/workspace.d.ts +8 -0
- package/dist/commands/doctor/workspace.d.ts.map +1 -1
- package/dist/commands/doctor/workspace.js +127 -3
- package/dist/commands/guard/commit.command.d.ts.map +1 -1
- package/dist/commands/guard/commit.command.js +30 -6
- package/dist/commands/guard/impl/allow.d.ts +4 -0
- package/dist/commands/guard/impl/allow.d.ts.map +1 -1
- package/dist/commands/guard/impl/allow.js +14 -3
- package/dist/commands/guard/impl/commands.d.ts.map +1 -1
- package/dist/commands/guard/impl/commands.js +11 -2
- package/dist/commands/shared/task-backend.d.ts +1 -1
- package/dist/commands/shared/task-backend.d.ts.map +1 -1
- package/dist/commands/shared/task-backend.js +9 -0
- package/dist/commands/shared/task-store.d.ts +61 -2
- package/dist/commands/shared/task-store.d.ts.map +1 -1
- package/dist/commands/shared/task-store.js +298 -60
- package/dist/commands/task/block.d.ts.map +1 -1
- package/dist/commands/task/block.js +58 -37
- package/dist/commands/task/close-shared.d.ts.map +1 -1
- package/dist/commands/task/close-shared.js +17 -20
- package/dist/commands/task/comment.d.ts.map +1 -1
- package/dist/commands/task/comment.js +14 -19
- package/dist/commands/task/derive.command.d.ts +1 -0
- package/dist/commands/task/derive.command.d.ts.map +1 -1
- package/dist/commands/task/derive.command.js +15 -2
- package/dist/commands/task/derive.d.ts +1 -0
- package/dist/commands/task/derive.d.ts.map +1 -1
- package/dist/commands/task/derive.js +27 -4
- package/dist/commands/task/doc.d.ts.map +1 -1
- package/dist/commands/task/doc.js +16 -5
- package/dist/commands/task/finish.d.ts.map +1 -1
- package/dist/commands/task/finish.js +41 -41
- package/dist/commands/task/migrate-doc.d.ts +15 -0
- package/dist/commands/task/migrate-doc.d.ts.map +1 -1
- package/dist/commands/task/migrate-doc.js +126 -35
- package/dist/commands/task/new.d.ts.map +1 -1
- package/dist/commands/task/new.js +3 -1
- package/dist/commands/task/plan.js +28 -28
- package/dist/commands/task/set-status.d.ts.map +1 -1
- package/dist/commands/task/set-status.js +104 -61
- package/dist/commands/task/shared/dependencies.d.ts +1 -0
- package/dist/commands/task/shared/dependencies.d.ts.map +1 -1
- package/dist/commands/task/shared/dependencies.js +10 -0
- package/dist/commands/task/shared/docs.js +1 -1
- package/dist/commands/task/shared/transitions.d.ts +17 -0
- package/dist/commands/task/shared/transitions.d.ts.map +1 -1
- package/dist/commands/task/shared/transitions.js +20 -7
- package/dist/commands/task/shared.d.ts +2 -2
- package/dist/commands/task/shared.d.ts.map +1 -1
- package/dist/commands/task/shared.js +2 -2
- package/dist/commands/task/start.d.ts.map +1 -1
- package/dist/commands/task/start.js +33 -28
- package/dist/commands/task/verify-record.d.ts.map +1 -1
- package/dist/commands/task/verify-record.js +32 -32
- package/dist/commands/upgrade/apply.d.ts +2 -0
- package/dist/commands/upgrade/apply.d.ts.map +1 -1
- package/dist/commands/upgrade/apply.js +33 -1
- package/dist/commands/upgrade.command.d.ts.map +1 -1
- package/dist/commands/upgrade.command.js +25 -0
- package/dist/commands/upgrade.d.ts +1 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +34 -0
- package/dist/policy/rules/allowlist.d.ts.map +1 -1
- package/dist/policy/rules/allowlist.js +12 -9
- package/dist/ports/task-backend-port.d.ts +2 -2
- package/dist/ports/task-backend-port.d.ts.map +1 -1
- package/dist/shared/protected-paths.d.ts +10 -0
- package/dist/shared/protected-paths.d.ts.map +1 -1
- package/dist/shared/protected-paths.js +33 -0
- package/package.json +2 -2
|
@@ -20,6 +20,12 @@ const REDMINE_ENV_TEMPLATE = [
|
|
|
20
20
|
comment: "Project identifier (numeric ID or project slug).",
|
|
21
21
|
required: true,
|
|
22
22
|
},
|
|
23
|
+
{
|
|
24
|
+
key: "AGENTPLANE_REDMINE_CUSTOM_FIELDS_TASK_ID",
|
|
25
|
+
value: "1",
|
|
26
|
+
comment: "Required Redmine custom field ID that stores the agentplane task id.",
|
|
27
|
+
required: true,
|
|
28
|
+
},
|
|
23
29
|
{
|
|
24
30
|
key: "AGENTPLANE_REDMINE_OWNER_AGENT",
|
|
25
31
|
value: "REDMINE",
|
|
@@ -32,6 +38,12 @@ const REDMINE_ENV_TEMPLATE = [
|
|
|
32
38
|
comment: "Optional assignee numeric ID.",
|
|
33
39
|
required: false,
|
|
34
40
|
},
|
|
41
|
+
{
|
|
42
|
+
key: "AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE",
|
|
43
|
+
value: "",
|
|
44
|
+
comment: "Optional Redmine custom field ID for structured canonical task state JSON.",
|
|
45
|
+
required: false,
|
|
46
|
+
},
|
|
35
47
|
];
|
|
36
48
|
async function readTextIfExists(filePath) {
|
|
37
49
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-cli.test-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.test-helpers.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAiD/D,wBAAgB,sBAAsB,IAAI,IAAI,CA8C7C;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAYtD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,YAAY;;;;EAgC3B;AAED,wBAAgB,YAAY,IAAI,MAAM,IAAI,CAkBzC;AAED,wBAAgB,eAAe,CAAC,SAAS,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"run-cli.test-helpers.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.test-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -169,6 +169,8 @@ export function stubTaskBackend(overrides = {}) {
|
|
|
169
169
|
projection: "canonical",
|
|
170
170
|
reads_from_projection_by_default: false,
|
|
171
171
|
writes_task_readmes: true,
|
|
172
|
+
supports_task_revisions: true,
|
|
173
|
+
supports_revision_guarded_writes: true,
|
|
172
174
|
may_access_network_on_read: false,
|
|
173
175
|
may_access_network_on_write: false,
|
|
174
176
|
supports_projection_refresh: false,
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import type { CommandCtx, CommandSpec } from "../../cli/spec/spec.js";
|
|
2
2
|
import type { CommandContext } from "../shared/task-backend.js";
|
|
3
|
-
import { type BackendSyncParsed } from "../backend.js";
|
|
3
|
+
import { type BackendInspectParsed, type BackendMigrateCanonicalStateParsed, type BackendSyncParsed } from "../backend.js";
|
|
4
4
|
type BackendRootParsed = {
|
|
5
5
|
cmd: string[];
|
|
6
6
|
};
|
|
7
7
|
export declare const backendSpec: CommandSpec<BackendRootParsed>;
|
|
8
8
|
export declare const backendSyncSpec: CommandSpec<BackendSyncParsed>;
|
|
9
|
+
export declare const backendMigrateCanonicalStateSpec: CommandSpec<BackendMigrateCanonicalStateParsed>;
|
|
10
|
+
export declare const backendInspectSpec: CommandSpec<BackendInspectParsed>;
|
|
9
11
|
declare function runBackendRootGroup(_ctx: CommandCtx, p: BackendRootParsed): Promise<number>;
|
|
10
12
|
export declare function makeRunBackendHandler(_getCtx: (cmd: string) => Promise<CommandContext>): typeof runBackendRootGroup;
|
|
11
13
|
export declare function makeRunBackendSyncHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BackendSyncParsed) => Promise<number>;
|
|
14
|
+
export declare function makeRunBackendInspectHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BackendInspectParsed) => Promise<number>;
|
|
15
|
+
export declare function makeRunBackendMigrateCanonicalStateHandler(getCtx: (cmd: string) => Promise<CommandContext>): (ctx: CommandCtx, p: BackendMigrateCanonicalStateParsed) => Promise<number>;
|
|
12
16
|
export {};
|
|
13
17
|
//# sourceMappingURL=sync.command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.command.d.ts","sourceRoot":"","sources":["../../../src/commands/backend/sync.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAItE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,
|
|
1
|
+
{"version":3,"file":"sync.command.d.ts","sourceRoot":"","sources":["../../../src/commands/backend/sync.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAItE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAIL,KAAK,oBAAoB,EACzB,KAAK,kCAAkC,EACvC,KAAK,iBAAiB,EACvB,MAAM,eAAe,CAAC;AAEvB,KAAK,iBAAiB,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE3C,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,iBAAiB,CAStD,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAuC1D,CAAC;AAEF,eAAO,MAAM,gCAAgC,EAAE,WAAW,CAAC,kCAAkC,CAoB5F,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,oBAAoB,CAoBhE,CAAC;AAEF,iBAAS,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAUpF;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,8BAEtF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC1E,KAAK,UAAU,EAAE,GAAG,iBAAiB,KAAG,OAAO,CAAC,MAAM,CAAC,CAStE;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC7E,KAAK,UAAU,EAAE,GAAG,oBAAoB,KAAG,OAAO,CAAC,MAAM,CAAC,CASzE;AAED,wBAAgB,0CAA0C,CACxD,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAElC,KAAK,UAAU,EAAE,GAAG,kCAAkC,KAAG,OAAO,CAAC,MAAM,CAAC,CASvF"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { COMMAND_SNIPPETS } from "../../cli/command-snippets.js";
|
|
2
2
|
import { usageError } from "../../cli/spec/errors.js";
|
|
3
3
|
import { suggestOne } from "../../cli/spec/suggest.js";
|
|
4
|
-
import { cmdBackendSyncParsed } from "../backend.js";
|
|
4
|
+
import { cmdBackendInspectParsed, cmdBackendMigrateCanonicalStateParsed, cmdBackendSyncParsed, } from "../backend.js";
|
|
5
5
|
export const backendSpec = {
|
|
6
6
|
id: ["backend"],
|
|
7
7
|
group: "Backend",
|
|
8
8
|
summary: "Backend-related operations.",
|
|
9
|
-
description: "This is a command group. Use a subcommand such as `agentplane backend sync ...`.",
|
|
9
|
+
description: "This is a command group. Use a subcommand such as `agentplane backend sync ...`, `agentplane backend inspect ...`, or `agentplane backend migrate-canonical-state ...`.",
|
|
10
10
|
args: [{ name: "cmd", required: false, variadic: true, valueHint: "<cmd>" }],
|
|
11
11
|
examples: [{ cmd: COMMAND_SNIPPETS.backendSync.pullLocal, why: "Sync the backend." }],
|
|
12
12
|
parse: (raw) => ({ cmd: (raw.args.cmd ?? []) }),
|
|
@@ -51,9 +51,51 @@ export const backendSyncSpec = {
|
|
|
51
51
|
quiet: raw.opts.quiet === true,
|
|
52
52
|
}),
|
|
53
53
|
};
|
|
54
|
+
export const backendMigrateCanonicalStateSpec = {
|
|
55
|
+
id: ["backend", "migrate-canonical-state"],
|
|
56
|
+
group: "Backend",
|
|
57
|
+
summary: "Backfill canonical_state for issues in the configured backend.",
|
|
58
|
+
args: [{ name: "id", required: true, valueHint: "<id>", description: "Configured backend id." }],
|
|
59
|
+
options: [
|
|
60
|
+
{ kind: "boolean", name: "yes", default: false, description: "Auto-approve network access." },
|
|
61
|
+
{ kind: "boolean", name: "quiet", default: false, description: "Reduce output noise." },
|
|
62
|
+
],
|
|
63
|
+
examples: [
|
|
64
|
+
{
|
|
65
|
+
cmd: "agentplane backend migrate-canonical-state redmine --yes",
|
|
66
|
+
why: "Backfill structured canonical_state into legacy Redmine issues.",
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
parse: (raw) => ({
|
|
70
|
+
backendId: String(raw.args.id),
|
|
71
|
+
yes: raw.opts.yes === true,
|
|
72
|
+
quiet: raw.opts.quiet === true,
|
|
73
|
+
}),
|
|
74
|
+
};
|
|
75
|
+
export const backendInspectSpec = {
|
|
76
|
+
id: ["backend", "inspect"],
|
|
77
|
+
group: "Backend",
|
|
78
|
+
summary: "Inspect visible backend readiness facts without mutating remote state.",
|
|
79
|
+
args: [{ name: "id", required: true, valueHint: "<id>", description: "Configured backend id." }],
|
|
80
|
+
options: [
|
|
81
|
+
{ kind: "boolean", name: "yes", default: false, description: "Auto-approve network access." },
|
|
82
|
+
{ kind: "boolean", name: "quiet", default: false, description: "Reduce output noise." },
|
|
83
|
+
],
|
|
84
|
+
examples: [
|
|
85
|
+
{
|
|
86
|
+
cmd: "agentplane backend inspect redmine --yes",
|
|
87
|
+
why: "Inspect visible Redmine custom fields and canonical_state readiness without remote writes.",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
parse: (raw) => ({
|
|
91
|
+
backendId: String(raw.args.id),
|
|
92
|
+
yes: raw.opts.yes === true,
|
|
93
|
+
quiet: raw.opts.quiet === true,
|
|
94
|
+
}),
|
|
95
|
+
};
|
|
54
96
|
function runBackendRootGroup(_ctx, p) {
|
|
55
97
|
const input = p.cmd.join(" ");
|
|
56
|
-
const suggestion = suggestOne(input, ["sync"]);
|
|
98
|
+
const suggestion = suggestOne(input, ["sync", "inspect", "migrate-canonical-state"]);
|
|
57
99
|
const suffix = suggestion ? ` Did you mean: ${suggestion}?` : "";
|
|
58
100
|
const msg = p.cmd.length === 0 ? "Missing subcommand." : `Unknown subcommand: ${p.cmd[0]}.`;
|
|
59
101
|
throw usageError({
|
|
@@ -76,3 +118,25 @@ export function makeRunBackendSyncHandler(getCtx) {
|
|
|
76
118
|
});
|
|
77
119
|
};
|
|
78
120
|
}
|
|
121
|
+
export function makeRunBackendInspectHandler(getCtx) {
|
|
122
|
+
return async (ctx, p) => {
|
|
123
|
+
const commandCtx = await getCtx("backend inspect");
|
|
124
|
+
return await cmdBackendInspectParsed({
|
|
125
|
+
ctx: commandCtx,
|
|
126
|
+
cwd: ctx.cwd,
|
|
127
|
+
rootOverride: ctx.rootOverride,
|
|
128
|
+
flags: p,
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export function makeRunBackendMigrateCanonicalStateHandler(getCtx) {
|
|
133
|
+
return async (ctx, p) => {
|
|
134
|
+
const commandCtx = await getCtx("backend migrate-canonical-state");
|
|
135
|
+
return await cmdBackendMigrateCanonicalStateParsed({
|
|
136
|
+
ctx: commandCtx,
|
|
137
|
+
cwd: ctx.cwd,
|
|
138
|
+
rootOverride: ctx.rootOverride,
|
|
139
|
+
flags: p,
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -13,6 +13,16 @@ export type SyncParsed = {
|
|
|
13
13
|
yes: boolean;
|
|
14
14
|
quiet: boolean;
|
|
15
15
|
};
|
|
16
|
+
export type BackendMigrateCanonicalStateParsed = {
|
|
17
|
+
backendId: string;
|
|
18
|
+
yes: boolean;
|
|
19
|
+
quiet: boolean;
|
|
20
|
+
};
|
|
21
|
+
export type BackendInspectParsed = {
|
|
22
|
+
backendId: string;
|
|
23
|
+
yes: boolean;
|
|
24
|
+
quiet: boolean;
|
|
25
|
+
};
|
|
16
26
|
export declare function cmdBackendSyncParsed(opts: {
|
|
17
27
|
ctx?: CommandContext;
|
|
18
28
|
cwd: string;
|
|
@@ -25,4 +35,16 @@ export declare function cmdSyncParsed(opts: {
|
|
|
25
35
|
rootOverride?: string;
|
|
26
36
|
flags: SyncParsed;
|
|
27
37
|
}): Promise<number>;
|
|
38
|
+
export declare function cmdBackendMigrateCanonicalStateParsed(opts: {
|
|
39
|
+
ctx?: CommandContext;
|
|
40
|
+
cwd: string;
|
|
41
|
+
rootOverride?: string;
|
|
42
|
+
flags: BackendMigrateCanonicalStateParsed;
|
|
43
|
+
}): Promise<number>;
|
|
44
|
+
export declare function cmdBackendInspectParsed(opts: {
|
|
45
|
+
ctx?: CommandContext;
|
|
46
|
+
cwd: string;
|
|
47
|
+
rootOverride?: string;
|
|
48
|
+
flags: BackendInspectParsed;
|
|
49
|
+
}): Promise<number>;
|
|
28
50
|
//# sourceMappingURL=backend.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/commands/backend.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAGnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB"}
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/commands/backend.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAGnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,MAAM,CAAC;IAC7D,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyClB;AAED,wBAAsB,qCAAqC,CAAC,IAAI,EAAE;IAChE,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,kCAAkC,CAAC;CAC3C,GAAG,OAAO,CAAC,MAAM,CAAC,CA2DlB;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE;IAClD,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,oBAAoB,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,CAkElB"}
|
package/dist/commands/backend.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { backendNotSupportedMessage } from "../cli/output.js";
|
|
1
|
+
import { backendNotSupportedMessage, successMessage, warnMessage } from "../cli/output.js";
|
|
2
2
|
import { mapBackendError } from "../cli/error-map.js";
|
|
3
3
|
import { CliError } from "../shared/errors.js";
|
|
4
4
|
import { loadCommandContext } from "./shared/task-backend.js";
|
|
@@ -89,3 +89,112 @@ export async function cmdSyncParsed(opts) {
|
|
|
89
89
|
throw mapBackendError(err, { command: "sync", root: opts.rootOverride ?? null });
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
+
export async function cmdBackendMigrateCanonicalStateParsed(opts) {
|
|
93
|
+
try {
|
|
94
|
+
const ctx = opts.ctx ??
|
|
95
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
96
|
+
const backend = ctx.taskBackend;
|
|
97
|
+
const backendId = ctx.backendId;
|
|
98
|
+
const config = ctx.config;
|
|
99
|
+
if (opts.flags.backendId && backendId && opts.flags.backendId !== backendId) {
|
|
100
|
+
throw new CliError({
|
|
101
|
+
exitCode: 2,
|
|
102
|
+
code: "E_USAGE",
|
|
103
|
+
message: `Configured backend is "${backendId}", not "${opts.flags.backendId}"`,
|
|
104
|
+
context: {
|
|
105
|
+
command: "backend migrate-canonical-state",
|
|
106
|
+
reason_code: "sync_backend_mismatch",
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (!backend.migrateCanonicalState) {
|
|
111
|
+
throw new CliError({
|
|
112
|
+
exitCode: 2,
|
|
113
|
+
code: "E_USAGE",
|
|
114
|
+
message: backendNotSupportedMessage("migrateCanonicalState()"),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (backendId !== "local") {
|
|
118
|
+
await ensureNetworkApproved({
|
|
119
|
+
config,
|
|
120
|
+
yes: opts.flags.yes,
|
|
121
|
+
reason: `backend migrate-canonical-state may access the network (backend: ${backendId})`,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const result = await backend.migrateCanonicalState();
|
|
125
|
+
if (!opts.flags.quiet) {
|
|
126
|
+
process.stdout.write(`${successMessage("backend migrate-canonical-state", undefined, `scanned=${result.scanned} migrated=${result.migrated.length} skipped-structured=${result.skippedStructured.length} skipped-no-doc=${result.skippedNoDoc.length} failed=${result.failed.length}`)}\n`);
|
|
127
|
+
}
|
|
128
|
+
if (result.failed.length > 0) {
|
|
129
|
+
for (const failure of result.failed.slice(0, 20)) {
|
|
130
|
+
process.stderr.write(`${warnMessage(`backend migrate-canonical-state failed for ${failure.taskId}: ${failure.reason}`)}\n`);
|
|
131
|
+
}
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
if (err instanceof CliError)
|
|
138
|
+
throw err;
|
|
139
|
+
throw mapBackendError(err, {
|
|
140
|
+
command: "backend migrate-canonical-state",
|
|
141
|
+
root: opts.rootOverride ?? null,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export async function cmdBackendInspectParsed(opts) {
|
|
146
|
+
try {
|
|
147
|
+
const ctx = opts.ctx ??
|
|
148
|
+
(await loadCommandContext({ cwd: opts.cwd, rootOverride: opts.rootOverride ?? null }));
|
|
149
|
+
const backend = ctx.taskBackend;
|
|
150
|
+
const backendId = ctx.backendId;
|
|
151
|
+
const config = ctx.config;
|
|
152
|
+
if (opts.flags.backendId && backendId && opts.flags.backendId !== backendId) {
|
|
153
|
+
throw new CliError({
|
|
154
|
+
exitCode: 2,
|
|
155
|
+
code: "E_USAGE",
|
|
156
|
+
message: `Configured backend is "${backendId}", not "${opts.flags.backendId}"`,
|
|
157
|
+
context: {
|
|
158
|
+
command: "backend inspect",
|
|
159
|
+
reason_code: "inspect_backend_mismatch",
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (!backend.inspectConfiguration) {
|
|
164
|
+
throw new CliError({
|
|
165
|
+
exitCode: 2,
|
|
166
|
+
code: "E_USAGE",
|
|
167
|
+
message: backendNotSupportedMessage("inspectConfiguration()"),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (backendId !== "local") {
|
|
171
|
+
await ensureNetworkApproved({
|
|
172
|
+
config,
|
|
173
|
+
yes: opts.flags.yes,
|
|
174
|
+
reason: `backend inspect may access the network (backend: ${backendId})`,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
const result = await backend.inspectConfiguration();
|
|
178
|
+
if (opts.flags.quiet)
|
|
179
|
+
return 0;
|
|
180
|
+
const canonicalStateSummary = result.canonicalState.configuredFieldId === null
|
|
181
|
+
? result.canonicalState.visibleFieldId === null
|
|
182
|
+
? "missing"
|
|
183
|
+
: `visible-unconfigured:${result.canonicalState.visibleFieldId}`
|
|
184
|
+
: `configured:${result.canonicalState.configuredFieldId}`;
|
|
185
|
+
process.stdout.write(`${successMessage("backend inspect", undefined, `visible-fields=${result.visibleCustomFields.length} canonical-state=${canonicalStateSummary} drift=${result.configuredFieldNameDrift.length}`)}\n`);
|
|
186
|
+
process.stdout.write(`canonical_state configured=${result.canonicalState.configuredFieldId ?? "unset"} visible=${result.canonicalState.visibleFieldId ?? "absent"}\n`);
|
|
187
|
+
for (const drift of result.configuredFieldNameDrift) {
|
|
188
|
+
process.stdout.write(`drift key=${drift.key} configured-id=${drift.configuredId} visible-name=${JSON.stringify(drift.visibleName)}\n`);
|
|
189
|
+
}
|
|
190
|
+
for (const field of result.visibleCustomFields) {
|
|
191
|
+
process.stdout.write(`field id=${field.id} name=${JSON.stringify(field.name)} non-empty=${field.nonEmptyCount}\n`);
|
|
192
|
+
}
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
if (err instanceof CliError)
|
|
197
|
+
throw err;
|
|
198
|
+
throw mapBackendError(err, { command: "backend inspect", root: opts.rootOverride ?? null });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.spec.d.ts","sourceRoot":"","sources":["../../src/commands/commit.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"commit.spec.d.ts","sourceRoot":"","sources":["../../src/commands/commit.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,kBAAkB,EAAE,OAAO,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,YAAY,CAwLhD,CAAC"}
|
|
@@ -49,23 +49,38 @@ export const commitSpec = {
|
|
|
49
49
|
kind: "boolean",
|
|
50
50
|
name: "allow-tasks",
|
|
51
51
|
default: false,
|
|
52
|
-
description: "Allow the tasks export snapshot plus artifacts under the active task subtree.",
|
|
52
|
+
description: "Allow the tasks export snapshot plus artifacts under the active task subtree; standalone path scope.",
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
kind: "boolean",
|
|
56
56
|
name: "allow-base",
|
|
57
57
|
default: false,
|
|
58
|
-
description: "Allow base branch edits.",
|
|
58
|
+
description: "Allow base branch edits; branch override only, not a path allowlist.",
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
61
|
kind: "boolean",
|
|
62
62
|
name: "allow-policy",
|
|
63
63
|
default: false,
|
|
64
|
-
description: "Allow policy edits (e.g. AGENTS.md).",
|
|
64
|
+
description: "Allow policy edits (e.g. AGENTS.md); standalone path scope.",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
kind: "boolean",
|
|
68
|
+
name: "allow-config",
|
|
69
|
+
default: false,
|
|
70
|
+
description: "Allow config edits; standalone path scope.",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
kind: "boolean",
|
|
74
|
+
name: "allow-hooks",
|
|
75
|
+
default: false,
|
|
76
|
+
description: "Allow hooks edits; standalone path scope.",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
kind: "boolean",
|
|
80
|
+
name: "allow-ci",
|
|
81
|
+
default: false,
|
|
82
|
+
description: "Allow CI workflow edits; standalone path scope.",
|
|
65
83
|
},
|
|
66
|
-
{ kind: "boolean", name: "allow-config", default: false, description: "Allow config edits." },
|
|
67
|
-
{ kind: "boolean", name: "allow-hooks", default: false, description: "Allow hooks edits." },
|
|
68
|
-
{ kind: "boolean", name: "allow-ci", default: false, description: "Allow CI workflow edits." },
|
|
69
84
|
{
|
|
70
85
|
kind: "boolean",
|
|
71
86
|
name: "require-clean",
|
|
@@ -79,11 +94,20 @@ export const commitSpec = {
|
|
|
79
94
|
cmd: 'agentplane commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: implement allowlist guard" --allow packages/agentplane',
|
|
80
95
|
why: "Create a commit after validating allowlist and subject policy.",
|
|
81
96
|
},
|
|
97
|
+
{
|
|
98
|
+
cmd: 'agentplane commit 202602030608-F1Q8AB -m "✨ F1Q8AB task: update publish workflow" --allow-ci',
|
|
99
|
+
why: "Commit CI-only changes without a redundant explicit workflow path prefix.",
|
|
100
|
+
},
|
|
82
101
|
{
|
|
83
102
|
cmd: "agentplane commit 202602030608-F1Q8AB --close",
|
|
84
103
|
why: "Create a close commit for the task README using a deterministic message builder.",
|
|
85
104
|
},
|
|
86
105
|
],
|
|
106
|
+
notes: [
|
|
107
|
+
"Protected path-scoped overrides can stand alone without a duplicate explicit prefix: `--allow-tasks`, `--allow-policy`, `--allow-config`, `--allow-hooks`, and `--allow-ci` each admit their own path family.",
|
|
108
|
+
"Top-level `agentplane commit` can auto-stage those protected path scopes when the git index starts empty.",
|
|
109
|
+
"`--allow-base` is different: it only overrides base-branch protection and never selects file paths by itself.",
|
|
110
|
+
],
|
|
87
111
|
validateRaw: (raw) => {
|
|
88
112
|
const close = raw.opts.close === true;
|
|
89
113
|
const msg = typeof raw.opts.message === "string" ? raw.opts.message.trim() : "";
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { type CommandContext } from "../shared/task-backend.js";
|
|
2
|
+
type TaskDocSnapshot = {
|
|
3
|
+
id?: unknown;
|
|
4
|
+
status?: unknown;
|
|
5
|
+
doc_version?: unknown;
|
|
6
|
+
};
|
|
7
|
+
export declare function buildTaskReadmeMigrationFindings(tasks: TaskDocSnapshot[]): string[];
|
|
8
|
+
export declare function checkTaskReadmeMigrationState(repoRoot: string, ctx?: CommandContext): Promise<string[]>;
|
|
2
9
|
export declare function checkWorkspace(repoRoot: string, opts?: {
|
|
3
10
|
ctx?: CommandContext;
|
|
4
11
|
}): Promise<string[]>;
|
|
12
|
+
export {};
|
|
5
13
|
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/workspace.ts"],"names":[],"mappings":"AAUA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEpF,KAAK,eAAe,GAAG;IACrB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAuFF,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAyDnF;AAED,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,cAAc,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC,CAOnB;AAuMD,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,cAAc,CAAA;CAAE,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC,CA2DnB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { parseTaskReadme, renderTaskDocFromSections } from "@agentplaneorg/core";
|
|
4
5
|
import { renderDiagnosticFinding } from "../../shared/diagnostics.js";
|
|
5
6
|
import { resolvePolicyGatewayForRepo } from "../../shared/policy-gateway.js";
|
|
6
7
|
import { GitContext } from "../shared/git-context.js";
|
|
@@ -84,7 +85,7 @@ async function readTaskDocSnapshotsFromProjection(ctx) {
|
|
|
84
85
|
return null;
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
|
-
function buildTaskReadmeMigrationFindings(tasks) {
|
|
88
|
+
export function buildTaskReadmeMigrationFindings(tasks) {
|
|
88
89
|
if (tasks.length === 0)
|
|
89
90
|
return [];
|
|
90
91
|
const legacy = tasks.filter((task) => task.doc_version !== 3);
|
|
@@ -138,7 +139,7 @@ function buildTaskReadmeMigrationFindings(tasks) {
|
|
|
138
139
|
}),
|
|
139
140
|
];
|
|
140
141
|
}
|
|
141
|
-
async function checkTaskReadmeMigrationState(repoRoot, ctx) {
|
|
142
|
+
export async function checkTaskReadmeMigrationState(repoRoot, ctx) {
|
|
142
143
|
const projectionTasks = await readTaskDocSnapshotsFromProjection(ctx);
|
|
143
144
|
const tasks = projectionTasks && projectionTasks.length > 0
|
|
144
145
|
? projectionTasks
|
|
@@ -197,6 +198,129 @@ async function checkDoneTaskReadmeArchiveDrift(repoRoot, ctx) {
|
|
|
197
198
|
}),
|
|
198
199
|
];
|
|
199
200
|
}
|
|
201
|
+
function normalizeTaskBodyForComparison(text) {
|
|
202
|
+
return text.replaceAll("\r\n", "\n").trim();
|
|
203
|
+
}
|
|
204
|
+
function normalizeCanonicalSections(value) {
|
|
205
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
206
|
+
return null;
|
|
207
|
+
const sections = {};
|
|
208
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
209
|
+
const title = key.trim();
|
|
210
|
+
if (!title || typeof entry !== "string")
|
|
211
|
+
continue;
|
|
212
|
+
sections[title] = entry;
|
|
213
|
+
}
|
|
214
|
+
return Object.keys(sections).length > 0 ? sections : null;
|
|
215
|
+
}
|
|
216
|
+
async function checkTaskProjectionDrift(repoRoot, ctx) {
|
|
217
|
+
const workflowDir = path.join(repoRoot, ctx?.config.paths.workflow_dir ?? ".agentplane/tasks");
|
|
218
|
+
let entries;
|
|
219
|
+
try {
|
|
220
|
+
entries = await fs.readdir(workflowDir, { withFileTypes: true });
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return [];
|
|
224
|
+
}
|
|
225
|
+
const drifted = [];
|
|
226
|
+
for (const entry of entries) {
|
|
227
|
+
if (!entry.isDirectory())
|
|
228
|
+
continue;
|
|
229
|
+
const readmePath = path.join(workflowDir, entry.name, "README.md");
|
|
230
|
+
let text = "";
|
|
231
|
+
try {
|
|
232
|
+
text = await fs.readFile(readmePath, "utf8");
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
let parsed;
|
|
238
|
+
try {
|
|
239
|
+
parsed = parseTaskReadme(text);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const sections = normalizeCanonicalSections(parsed.frontmatter.sections);
|
|
245
|
+
if (!sections)
|
|
246
|
+
continue;
|
|
247
|
+
const renderedBody = renderTaskDocFromSections(sections);
|
|
248
|
+
if (normalizeTaskBodyForComparison(parsed.body) === normalizeTaskBodyForComparison(renderedBody)) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const taskId = typeof parsed.frontmatter.id === "string" && parsed.frontmatter.id.trim()
|
|
252
|
+
? parsed.frontmatter.id.trim()
|
|
253
|
+
: entry.name;
|
|
254
|
+
const status = typeof parsed.frontmatter.status === "string" && parsed.frontmatter.status.trim()
|
|
255
|
+
? parsed.frontmatter.status.trim().toUpperCase()
|
|
256
|
+
: "UNKNOWN";
|
|
257
|
+
drifted.push({ id: taskId, status });
|
|
258
|
+
}
|
|
259
|
+
if (drifted.length === 0)
|
|
260
|
+
return [];
|
|
261
|
+
const activeCount = drifted.filter((task) => task.status !== "DONE").length;
|
|
262
|
+
const examples = drifted
|
|
263
|
+
.slice(0, 5)
|
|
264
|
+
.map((task) => `${task.id}[${task.status}]`)
|
|
265
|
+
.join(", ");
|
|
266
|
+
return [
|
|
267
|
+
renderDiagnosticFinding({
|
|
268
|
+
severity: "WARN",
|
|
269
|
+
state: "task README projection drift detected",
|
|
270
|
+
likelyCause: "canonical frontmatter.sections no longer match the rendered task body on disk",
|
|
271
|
+
nextAction: {
|
|
272
|
+
command: "agentplane task normalize",
|
|
273
|
+
reason: "re-render task README bodies from canonical one-file task state",
|
|
274
|
+
},
|
|
275
|
+
details: [
|
|
276
|
+
`Drifted task READMEs: ${drifted.length}; active drifted tasks: ${activeCount}`,
|
|
277
|
+
examples ? `Examples: ${examples}` : "Examples unavailable.",
|
|
278
|
+
],
|
|
279
|
+
}),
|
|
280
|
+
];
|
|
281
|
+
}
|
|
282
|
+
function checkBackendReadiness(ctx) {
|
|
283
|
+
if (ctx?.backendId !== "redmine")
|
|
284
|
+
return [];
|
|
285
|
+
const { supports_task_revisions, supports_revision_guarded_writes } = ctx.taskBackend.capabilities;
|
|
286
|
+
if (supports_task_revisions === supports_revision_guarded_writes &&
|
|
287
|
+
supports_task_revisions === true) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
if (supports_task_revisions === false && supports_revision_guarded_writes === false) {
|
|
291
|
+
return [
|
|
292
|
+
renderDiagnosticFinding({
|
|
293
|
+
severity: "WARN",
|
|
294
|
+
state: "Redmine backend is running in partial compatibility mode without canonical_state support",
|
|
295
|
+
likelyCause: "AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE is not configured, so Redmine cannot round-trip the full canonical task state or guard writes by remote revision",
|
|
296
|
+
nextAction: {
|
|
297
|
+
command: "agentplane backend inspect redmine --yes",
|
|
298
|
+
reason: "inspect visible Redmine custom fields first, then wire AGENTPLANE_REDMINE_CUSTOM_FIELDS_CANONICAL_STATE to the correct field id",
|
|
299
|
+
},
|
|
300
|
+
details: [
|
|
301
|
+
`Backend config: ${ctx.backendConfigPath}`,
|
|
302
|
+
"Current capability flags: supports_task_revisions=false; supports_revision_guarded_writes=false",
|
|
303
|
+
"Legacy doc field syncing can still work, but the backend remains partial-compatibility only.",
|
|
304
|
+
],
|
|
305
|
+
}),
|
|
306
|
+
];
|
|
307
|
+
}
|
|
308
|
+
return [
|
|
309
|
+
renderDiagnosticFinding({
|
|
310
|
+
severity: "WARN",
|
|
311
|
+
state: "Redmine backend capability contract is internally inconsistent",
|
|
312
|
+
likelyCause: "backend capability flags diverged, so doctor cannot rely on a single revision-guard readiness state",
|
|
313
|
+
nextAction: {
|
|
314
|
+
command: "inspect Redmine backend capability wiring and rerun agentplane doctor",
|
|
315
|
+
reason: "restore a coherent readiness contract before relying on guarded remote writes",
|
|
316
|
+
},
|
|
317
|
+
details: [
|
|
318
|
+
`Backend config: ${ctx.backendConfigPath}`,
|
|
319
|
+
`Current capability flags: supports_task_revisions=${String(supports_task_revisions)}; supports_revision_guarded_writes=${String(supports_revision_guarded_writes)}`,
|
|
320
|
+
],
|
|
321
|
+
}),
|
|
322
|
+
];
|
|
323
|
+
}
|
|
200
324
|
export async function checkWorkspace(repoRoot, opts) {
|
|
201
325
|
const problems = [];
|
|
202
326
|
const requiredFiles = [path.join(repoRoot, ".agentplane", "config.json")];
|
|
@@ -243,6 +367,6 @@ export async function checkWorkspace(repoRoot, opts) {
|
|
|
243
367
|
if (!hasJson) {
|
|
244
368
|
problems.push("No agent profiles found in .agentplane/agents (*.json expected).");
|
|
245
369
|
}
|
|
246
|
-
problems.push(...(await checkTaskReadmeMigrationState(repoRoot, opts?.ctx)), ...(await checkDoneTaskReadmeArchiveDrift(repoRoot, opts?.ctx)));
|
|
370
|
+
problems.push(...checkBackendReadiness(opts?.ctx), ...(await checkTaskReadmeMigrationState(repoRoot, opts?.ctx)), ...(await checkDoneTaskReadmeArchiveDrift(repoRoot, opts?.ctx)), ...(await checkTaskProjectionDrift(repoRoot, opts?.ctx)));
|
|
247
371
|
return problems;
|
|
248
372
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.command.d.ts","sourceRoot":"","sources":["../../../src/commands/guard/commit.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAOtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"commit.command.d.ts","sourceRoot":"","sources":["../../../src/commands/guard/commit.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAOtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,iBAAiB,CAmI1D,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,IAC1E,KAAK,UAAU,EAAE,GAAG,iBAAiB,KAAG,OAAO,CAAC,MAAM,CAAC,CA2BtE"}
|