@gavin-hu/my-pi-agent 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -33
- package/README.zh-CN.md +44 -27
- package/extensions/bytefly/README.md +193 -140
- package/extensions/bytefly/block/component.ts +7 -15
- package/extensions/bytefly/block/register.ts +6 -1
- package/extensions/bytefly/doctor/register.ts +24 -5
- package/extensions/bytefly/doctor/tools.ts +4 -0
- package/extensions/bytefly/footer/collect/snapshot.ts +6 -1
- package/extensions/bytefly/footer/config.ts +10 -6
- package/extensions/bytefly/footer/price/price.ts +5 -3
- package/extensions/bytefly/footer/price/rates.ts +63 -26
- package/extensions/bytefly/footer/render/status.ts +3 -3
- package/extensions/bytefly/header/component.ts +3 -2
- package/extensions/bytefly/index.ts +3 -3
- package/extensions/bytefly/notice/component.ts +8 -3
- package/extensions/bytefly/notify/config.ts +6 -11
- package/extensions/bytefly/notify/dispatch.ts +13 -5
- package/extensions/bytefly/panel/commands.ts +21 -1
- package/extensions/bytefly/panel/format.ts +5 -2
- package/extensions/bytefly/panel/settings-runtime.ts +26 -6
- package/extensions/bytefly/panel/settings.ts +41 -4
- package/extensions/bytefly/panel/themes.ts +32 -0
- package/extensions/bytefly/panel/tui/editing.ts +77 -0
- package/extensions/bytefly/panel/tui/entries.ts +24 -0
- package/extensions/bytefly/panel/tui/extensions-view.ts +13 -8
- package/extensions/bytefly/panel/tui/frame.ts +121 -4
- package/extensions/bytefly/panel/tui/settings-view.ts +54 -15
- package/extensions/bytefly/panel/tui.ts +94 -152
- package/extensions/bytefly/picker/discovery.ts +1 -0
- package/extensions/bytefly/picker/types.ts +2 -0
- package/extensions/bytefly/separator/component.ts +14 -4
- package/extensions/bytefly/update/cache.ts +58 -19
- package/extensions/bytefly/update/check.ts +35 -0
- package/extensions/bytefly/update/format.ts +76 -35
- package/extensions/bytefly/update/register.ts +144 -55
- package/extensions/bytefly/update/state.ts +4 -2
- package/extensions/bytefly/update/suppress.ts +66 -0
- package/extensions/bytefly/update/types.ts +15 -0
- package/extensions/check/README.md +253 -0
- package/extensions/check/commands.ts +128 -0
- package/extensions/check/config.ts +39 -0
- package/extensions/check/detect.ts +269 -0
- package/extensions/check/failures.ts +230 -0
- package/extensions/check/format.ts +135 -0
- package/extensions/check/index.ts +26 -0
- package/extensions/check/render.ts +185 -0
- package/extensions/check/runner.ts +176 -0
- package/extensions/check/runtime.ts +244 -0
- package/extensions/check/source.ts +80 -0
- package/extensions/check/tools.ts +173 -0
- package/extensions/check/tui.ts +195 -0
- package/extensions/check/types.ts +99 -0
- package/extensions/document/README.md +1 -1
- package/extensions/document/extract/pdf.ts +8 -16
- package/extensions/document/formats.ts +2 -2
- package/extensions/file-browse/README.md +66 -32
- package/extensions/file-browse/client.ts +95 -32
- package/extensions/file-browse/config.ts +9 -9
- package/extensions/file-browse/git.ts +37 -47
- package/extensions/file-browse/html.ts +39 -58
- package/extensions/file-browse/markdown.ts +110 -92
- package/extensions/file-browse/raw-html.ts +478 -0
- package/extensions/file-browse/router.ts +32 -70
- package/extensions/file-browse/server.ts +18 -56
- package/extensions/file-browse/urls.ts +80 -0
- package/extensions/goal/README.md +103 -47
- package/extensions/goal/clarify-parse.ts +4 -9
- package/extensions/goal/clarify.ts +27 -4
- package/extensions/goal/commands.ts +24 -11
- package/extensions/goal/format.ts +41 -10
- package/extensions/goal/index.ts +39 -16
- package/extensions/goal/plan-route.ts +51 -0
- package/extensions/goal/schema.ts +6 -23
- package/extensions/goal/state.ts +39 -57
- package/extensions/goal/tools.ts +26 -20
- package/extensions/goal/types.ts +11 -1
- package/extensions/job/README.md +20 -6
- package/extensions/job/format.ts +18 -68
- package/extensions/job/index.ts +26 -41
- package/extensions/job/log-writer.ts +208 -0
- package/extensions/job/logs.ts +3 -2
- package/extensions/job/process.ts +6 -99
- package/extensions/job/runtime.ts +42 -181
- package/extensions/job/schema.ts +1 -4
- package/extensions/job/tools.ts +1 -15
- package/extensions/job/tui.ts +117 -307
- package/extensions/job/ui.ts +7 -33
- package/extensions/memory/README.md +1 -1
- package/extensions/memory/errors.ts +5 -6
- package/extensions/memory/tui.ts +14 -24
- package/extensions/plan/README.md +94 -18
- package/extensions/plan/commands.ts +9 -5
- package/extensions/plan/format.ts +87 -0
- package/extensions/plan/index.ts +31 -15
- package/extensions/plan/plans.ts +2 -3
- package/extensions/plan/policy.ts +0 -6
- package/extensions/plan/runtime.ts +4 -2
- package/extensions/plan/steps.ts +37 -8
- package/extensions/plan/todos.ts +44 -3
- package/extensions/plan/tools/enter.ts +94 -0
- package/extensions/plan/tools/exit.ts +296 -0
- package/extensions/plan/tools/nested.ts +21 -0
- package/extensions/plan/tools/steps.ts +136 -0
- package/extensions/plan/tools/todo-seed.ts +76 -0
- package/extensions/plan/tools/write.ts +127 -0
- package/extensions/plan/tools.ts +18 -703
- package/extensions/plan/web-client.ts +6 -22
- package/extensions/plan/web-page.ts +19 -30
- package/extensions/plan/web-router.ts +34 -71
- package/extensions/plan/web.ts +13 -40
- package/extensions/question/answers.ts +3 -8
- package/extensions/question/tui.ts +6 -6
- package/extensions/rewind/README.md +95 -22
- package/extensions/rewind/checklist.ts +185 -0
- package/extensions/rewind/commands.ts +8 -0
- package/extensions/rewind/config.ts +3 -11
- package/extensions/rewind/format.ts +220 -2
- package/extensions/rewind/git.ts +74 -7
- package/extensions/rewind/hunk-picker.ts +114 -0
- package/extensions/rewind/patch.ts +88 -0
- package/extensions/rewind/path-picker.ts +67 -100
- package/extensions/rewind/paths.ts +93 -19
- package/extensions/rewind/restore.ts +53 -10
- package/extensions/rewind/review-tui.ts +320 -0
- package/extensions/rewind/review.ts +397 -0
- package/extensions/rewind/rewind-tui.ts +4 -3
- package/extensions/rewind/runtime.ts +94 -17
- package/extensions/subagent/README.md +61 -6
- package/extensions/subagent/background-tui.ts +208 -0
- package/extensions/subagent/background.ts +470 -0
- package/extensions/subagent/commands.ts +80 -0
- package/extensions/subagent/config.ts +4 -0
- package/extensions/subagent/format.ts +24 -1
- package/extensions/subagent/index.ts +91 -2
- package/extensions/subagent/render.ts +13 -0
- package/extensions/subagent/run.ts +17 -16
- package/extensions/subagent/schema.ts +12 -0
- package/extensions/subagent/types.ts +11 -0
- package/extensions/subagent/ui.ts +50 -0
- package/extensions/todo/README.md +18 -13
- package/extensions/todo/format.ts +3 -2
- package/extensions/todo/runtime.ts +3 -2
- package/extensions/todo/schema.ts +8 -84
- package/extensions/todo/state.ts +5 -46
- package/extensions/todo/tools.ts +2 -1
- package/extensions/todo/types.ts +6 -15
- package/extensions/watch/README.md +14 -6
- package/extensions/watch/child.ts +150 -0
- package/extensions/watch/format.ts +8 -48
- package/extensions/watch/index.ts +42 -58
- package/extensions/watch/runtime.ts +49 -128
- package/extensions/watch/schema.ts +1 -4
- package/extensions/watch/tools.ts +1 -11
- package/extensions/watch/tui.ts +103 -273
- package/extensions/watch/ui.ts +5 -32
- package/extensions/web-access/README.md +1 -1
- package/extensions/web-access/fetch/page.ts +1 -1
- package/extensions/web-access/fetch/tool.ts +6 -2
- package/extensions/web-access/search/search.ts +2 -5
- package/extensions/wechat/README.md +1 -1
- package/extensions/wechat/client.ts +23 -0
- package/extensions/wechat/commands.ts +57 -42
- package/extensions/wechat/deliver.ts +5 -9
- package/extensions/wechat/errors.ts +3 -6
- package/extensions/wechat/inbound.ts +2 -5
- package/extensions/wechat/index.ts +2 -8
- package/extensions/wechat/outbound.ts +2 -4
- package/extensions/wechat/peer-worker.ts +3 -8
- package/extensions/wechat/poll.ts +10 -9
- package/extensions/wechat/presence.ts +35 -62
- package/extensions/wechat/reply-pipeline.ts +3 -1
- package/extensions/wechat/status-screen.ts +1 -1
- package/extensions/wechat/timer.ts +57 -0
- package/extensions/worktree/config.ts +8 -20
- package/extensions/worktree/enter.ts +7 -12
- package/extensions/worktree/git.ts +38 -69
- package/extensions/worktree/index.ts +5 -4
- package/extensions/worktree/registry.ts +7 -7
- package/extensions/worktree/root-tools.ts +2 -2
- package/extensions/worktree/status.ts +3 -2
- package/lib/README.md +22 -8
- package/lib/config.ts +50 -3
- package/lib/errors.ts +12 -0
- package/lib/format.ts +50 -0
- package/lib/git/read.ts +8 -0
- package/lib/goal-state.ts +23 -8
- package/lib/http/headers.ts +54 -0
- package/lib/http/index.ts +13 -0
- package/lib/http/response.ts +46 -0
- package/lib/http/router.ts +52 -0
- package/lib/http/server.ts +91 -0
- package/lib/lines.ts +77 -0
- package/lib/pdf.ts +82 -0
- package/lib/plan-entry.ts +71 -0
- package/lib/plan-state.ts +34 -0
- package/lib/report.ts +99 -0
- package/lib/requirements.ts +25 -19
- package/lib/spawn.ts +170 -0
- package/lib/todo-state.ts +110 -23
- package/lib/tool-names.ts +7 -0
- package/lib/tool-result.ts +33 -0
- package/lib/tui/README.md +68 -3
- package/lib/tui/chrome.ts +28 -4
- package/lib/tui/columns.ts +6 -1
- package/lib/tui/confirm.ts +65 -0
- package/lib/tui/dock-screen.ts +410 -0
- package/lib/tui/glyphs.ts +2 -1
- package/lib/tui/indent.ts +1 -1
- package/lib/tui/index.ts +2 -0
- package/lib/tui/rows.ts +21 -0
- package/lib/tui/status-controller.ts +35 -1
- package/lib/tui/tool.ts +59 -1
- package/lib/web/components.ts +20 -1
- package/lib/web/markup.ts +32 -0
- package/lib/web/runtime.ts +50 -0
- package/package.json +22 -5
- package/skills/init/SKILL.md +165 -0
- package/skills/init/references/agents-md-quality.md +103 -0
- package/skills/init/references/interview-questions.md +81 -0
- package/skills/refactor/SKILL.md +141 -0
- package/extensions/watch/process.ts +0 -63
- package/extensions/web-access/fetch/pdf.ts +0 -45
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two nested `todo` writes the plan tools make: seeding a new plan's steps
|
|
3
|
+
* at approval, and mirroring a step update into the items that came from it.
|
|
4
|
+
*
|
|
5
|
+
* The todo list is whole-list replacement, so both go through `todos.ts`'s pure
|
|
6
|
+
* merge/mirror against the list the branch holds, and both report a nested
|
|
7
|
+
* failure in the result rather than becoming error results.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ExtensionAPI, ExtensionToolContext } from "@earendil-works/pi-coding-agent";
|
|
11
|
+
import { TODO_TOOL } from "../../../lib/tool-names.ts";
|
|
12
|
+
import { lastTodos } from "../../../lib/todo-state.ts";
|
|
13
|
+
import { extractPlanSteps, verificationItem, type PlanStep, type StepUpdate } from "../steps.ts";
|
|
14
|
+
import { DEFAULT_TODO_MAX, mergeTodos, mirrorStepStatuses, type TodoMerge } from "../todos.ts";
|
|
15
|
+
import { firstTextLine } from "./nested.ts";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The todo tool's item cap, read from its registered schema so the merge stops
|
|
19
|
+
* before the nested call would reject the list. Falls back to the documented
|
|
20
|
+
* default when the tool is absent or has not declared one.
|
|
21
|
+
*/
|
|
22
|
+
function todoMaxItems(pi: ExtensionAPI): number {
|
|
23
|
+
const info = pi.getAllTools().find((tool) => tool.name === TODO_TOOL);
|
|
24
|
+
const parameters = info?.parameters as { properties?: { todos?: { maxItems?: unknown } } } | undefined;
|
|
25
|
+
const max = parameters?.properties?.todos?.maxItems;
|
|
26
|
+
return typeof max === "number" && Number.isInteger(max) && max > 0 ? max : DEFAULT_TODO_MAX;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Record the plan's steps in the todo list. The list is whole-list replacement,
|
|
31
|
+
* so the steps are merged into what the branch already holds: existing items
|
|
32
|
+
* keep their place and status, duplicates are skipped, and the cap defers the
|
|
33
|
+
* rest. Returns what happened for the approval message.
|
|
34
|
+
*/
|
|
35
|
+
export async function seedTodos(
|
|
36
|
+
pi: ExtensionAPI,
|
|
37
|
+
ctx: ExtensionToolContext,
|
|
38
|
+
plan: string,
|
|
39
|
+
): Promise<{ steps: PlanStep[]; merged?: TodoMerge; error?: string }> {
|
|
40
|
+
const steps = extractPlanSteps(plan);
|
|
41
|
+
const verification = verificationItem(plan);
|
|
42
|
+
if (steps.length === 0 && !verification) return { steps };
|
|
43
|
+
const merged = mergeTodos(lastTodos(ctx.sessionManager.getBranch()), steps, todoMaxItems(pi), verification);
|
|
44
|
+
// Nothing new to write: every step (and the verification item) is already in
|
|
45
|
+
// the list, or the list is full, so a rewrite would only churn the widget.
|
|
46
|
+
if (merged.added === 0 && merged.trailing !== "added") return { steps, merged };
|
|
47
|
+
const outcome = await ctx.executeTool(TODO_TOOL, { todos: merged.todos });
|
|
48
|
+
if (!outcome.isError) return { steps, merged };
|
|
49
|
+
// The nested call fails both when the tool is unavailable and when it rejects
|
|
50
|
+
// the steps; surface its first line so the caller reports the real reason.
|
|
51
|
+
return { steps, merged, error: firstTextLine(outcome) };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Bring the todo items seeded at approval in line with the batch, and describe
|
|
56
|
+
* what happened for the result text.
|
|
57
|
+
*
|
|
58
|
+
* The plan file is authoritative and has already been written, so a nested
|
|
59
|
+
* failure is reported in the result instead of becoming an error result: once
|
|
60
|
+
* one of the two artifacts changed there is no previous state to hand back.
|
|
61
|
+
* Nothing is written when no item changed, so a repeated call does not churn the
|
|
62
|
+
* widget.
|
|
63
|
+
*/
|
|
64
|
+
export async function mirrorTodos(ctx: ExtensionToolContext, updates: readonly StepUpdate[]): Promise<string> {
|
|
65
|
+
const mirror = mirrorStepStatuses(lastTodos(ctx.sessionManager.getBranch()), updates);
|
|
66
|
+
if (mirror.updated === 0) {
|
|
67
|
+
if (mirror.unmatched === 0) return "";
|
|
68
|
+
const steps = mirror.unmatched === 1 ? "1 step has" : `${mirror.unmatched} steps have`;
|
|
69
|
+
return `; ${steps} no matching todo item`;
|
|
70
|
+
}
|
|
71
|
+
const items = mirror.updated === 1 ? "1 todo item" : `${mirror.updated} todo items`;
|
|
72
|
+
const outcome = await ctx.executeTool(TODO_TOOL, { todos: mirror.todos });
|
|
73
|
+
if (!outcome.isError) return `; ${items} updated`;
|
|
74
|
+
const firstLine = firstTextLine(outcome);
|
|
75
|
+
return `; could not update ${items} in the todo list${firstLine ? `: ${firstLine}` : ""}`;
|
|
76
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `write_plan` tool registration.
|
|
3
|
+
*
|
|
4
|
+
* The cap refusal happens before the file is written, so approval never lists a
|
|
5
|
+
* step it cannot track; the store owns naming, containment, and atomicity.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { Type, type Static } from "typebox";
|
|
10
|
+
import { sanitizeLine } from "../../../lib/format.ts";
|
|
11
|
+
import { reuseText, toolDetails } from "../../../lib/tui/chrome.ts";
|
|
12
|
+
import { GLYPHS } from "../../../lib/tui/glyphs.ts";
|
|
13
|
+
import { paint } from "../../../lib/tui/tokens.ts";
|
|
14
|
+
import { rejectionLine, reuseCallText, toolCallTitle } from "../../../lib/tui/tool.ts";
|
|
15
|
+
import { overCap, stepElisionNote } from "../format.ts";
|
|
16
|
+
import { WRITE_PLAN_TOOL, type PlanRuntime } from "../runtime.ts";
|
|
17
|
+
import { MAX_STEPS, PLAN_OUTLINE, planStepSummary } from "../steps.ts";
|
|
18
|
+
import type { WritePlanDetails } from "../types.ts";
|
|
19
|
+
|
|
20
|
+
const WritePlanParams = Type.Object({
|
|
21
|
+
title: Type.String({
|
|
22
|
+
description: 'Short title for the plan, used as the file-name slug, e.g. "Add rate limiting".',
|
|
23
|
+
}),
|
|
24
|
+
content: Type.String({
|
|
25
|
+
description: "The complete plan as markdown in the documented outline, including every step.",
|
|
26
|
+
}),
|
|
27
|
+
plan_path: Type.Optional(
|
|
28
|
+
Type.String({
|
|
29
|
+
description:
|
|
30
|
+
"Overwrite an existing plan file (one returned by an earlier write_plan) to refine it instead of creating a new file.",
|
|
31
|
+
}),
|
|
32
|
+
),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
type WritePlanArgs = Static<typeof WritePlanParams>;
|
|
36
|
+
|
|
37
|
+
export function registerWriteTool(pi: ExtensionAPI, runtime: PlanRuntime): void {
|
|
38
|
+
pi.registerTool({
|
|
39
|
+
name: WRITE_PLAN_TOOL,
|
|
40
|
+
label: "Write plan",
|
|
41
|
+
description:
|
|
42
|
+
"Save the plan you designed as a markdown file under .pi/plans (project root, or the agent directory outside a " +
|
|
43
|
+
"repository). Write the complete plan, not a summary, in this outline so it is consistent and scannable:\n\n" +
|
|
44
|
+
`${PLAN_OUTLINE}\n\n` +
|
|
45
|
+
"Returns the path to pass to exit_plan_mode; plan_path overwrites an existing file when refining. " +
|
|
46
|
+
`A plan with more than ${MAX_STEPS} top-level steps in its Steps section is refused, so approval never drops steps it cannot track.`,
|
|
47
|
+
promptSnippet: "Save the designed plan as a markdown file under .pi/plans.",
|
|
48
|
+
promptGuidelines: [
|
|
49
|
+
"While plan mode is active, write the full plan with write_plan, then call exit_plan_mode with the returned path.",
|
|
50
|
+
],
|
|
51
|
+
parameters: WritePlanParams,
|
|
52
|
+
defaultActive: false,
|
|
53
|
+
executionMode: "sequential",
|
|
54
|
+
// destructiveHint is true because plan_path overwrites an existing plan
|
|
55
|
+
// file; a plain write creates a new one.
|
|
56
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
|
|
57
|
+
|
|
58
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
59
|
+
if (!runtime.isEnabled()) {
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: "text", text: "Not in plan mode; call enter_plan_mode first." }],
|
|
62
|
+
details: undefined,
|
|
63
|
+
isError: true,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const args = params as WritePlanArgs;
|
|
67
|
+
const summary = planStepSummary(args.content);
|
|
68
|
+
if (summary.total > MAX_STEPS) {
|
|
69
|
+
// Refuse before writing: a note after the fact arrives once the file exists and
|
|
70
|
+
// the review has listed every step, so the overflow is already lost.
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: `${overCap(summary.total)} Nothing was written; group the steps (one outcome each, sub-bullets for detail) and call write_plan again.`,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
details: undefined,
|
|
79
|
+
isError: true,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const file = await runtime.plans.write(ctx.cwd, {
|
|
84
|
+
title: args.title,
|
|
85
|
+
content: args.content,
|
|
86
|
+
planPath: args.plan_path,
|
|
87
|
+
});
|
|
88
|
+
runtime.setLastPlan(ctx, file.path);
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: "text",
|
|
93
|
+
text: `Wrote the plan to ${file.relativePath}. Call exit_plan_mode with plan_path: ${file.path}${stepElisionNote(summary.elided)}`,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
details: { path: file.path, relativePath: file.relativePath, bytes: file.bytes } satisfies WritePlanDetails,
|
|
97
|
+
};
|
|
98
|
+
} catch (error) {
|
|
99
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
100
|
+
return {
|
|
101
|
+
content: [{ type: "text", text: `Could not write the plan: ${message}` }],
|
|
102
|
+
details: undefined,
|
|
103
|
+
isError: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
renderCall(args, theme, context) {
|
|
109
|
+
const text = reuseCallText(context?.lastComponent);
|
|
110
|
+
const title = (args as Partial<WritePlanArgs>).title;
|
|
111
|
+
const suffix = title ? paint(theme, "meta", sanitizeLine(title)) : paint(theme, "meta", "plan");
|
|
112
|
+
text.setText(toolCallTitle(theme, `${WRITE_PLAN_TOOL} `) + suffix);
|
|
113
|
+
return text;
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
renderResult(result, options, theme, context) {
|
|
117
|
+
const text = reuseText(context?.lastComponent);
|
|
118
|
+
const details = toolDetails<WritePlanDetails>(result.details);
|
|
119
|
+
if (!details) {
|
|
120
|
+
text.setText(rejectionLine(theme, result, options.expanded));
|
|
121
|
+
return text;
|
|
122
|
+
}
|
|
123
|
+
text.setText(paint(theme, "ok", `${GLYPHS.check} Saved plan `) + paint(theme, "meta", details.relativePath));
|
|
124
|
+
return text;
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|