pi-ui-extend 0.1.9 → 0.1.13
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 +23 -2
- package/dist/app/app.d.ts +4 -0
- package/dist/app/app.js +76 -7
- package/dist/app/cli/install.d.ts +16 -0
- package/dist/app/cli/install.js +34 -7
- package/dist/app/cli/startup-info.js +5 -2
- package/dist/app/cli/update.d.ts +7 -0
- package/dist/app/cli/update.js +11 -3
- package/dist/app/commands/command-controller.js +4 -0
- package/dist/app/commands/command-host.d.ts +4 -0
- package/dist/app/commands/command-model-actions.d.ts +5 -0
- package/dist/app/commands/command-model-actions.js +104 -0
- package/dist/app/commands/command-navigation-actions.d.ts +6 -1
- package/dist/app/commands/command-navigation-actions.js +37 -14
- package/dist/app/commands/command-registry.d.ts +4 -0
- package/dist/app/commands/command-registry.js +32 -0
- package/dist/app/commands/command-session-actions.d.ts +1 -0
- package/dist/app/commands/command-session-actions.js +15 -5
- package/dist/app/commands/shell-command.d.ts +7 -0
- package/dist/app/commands/shell-command.js +12 -4
- package/dist/app/commands/shell-controller.d.ts +1 -0
- package/dist/app/commands/shell-controller.js +1 -1
- package/dist/app/constants.d.ts +1 -1
- package/dist/app/constants.js +1 -1
- package/dist/app/icons.d.ts +1 -0
- package/dist/app/icons.js +3 -1
- package/dist/app/input/autocomplete-controller.d.ts +52 -0
- package/dist/app/input/autocomplete-controller.js +352 -0
- package/dist/app/input/input-action-controller.d.ts +1 -0
- package/dist/app/input/input-action-controller.js +21 -0
- package/dist/app/input/input-controller.d.ts +1 -0
- package/dist/app/input/input-controller.js +2 -0
- package/dist/app/input/input-paste-handler.d.ts +1 -0
- package/dist/app/input/input-paste-handler.js +22 -18
- package/dist/app/input/prompt-enhancer-controller.d.ts +7 -1
- package/dist/app/input/prompt-enhancer-controller.js +12 -3
- package/dist/app/input/voice-controller.d.ts +51 -1
- package/dist/app/input/voice-controller.js +42 -19
- package/dist/app/model/model-usage-status.d.ts +9 -0
- package/dist/app/model/model-usage-status.js +124 -34
- package/dist/app/popup/popup-action-controller.js +1 -1
- package/dist/app/process.d.ts +17 -0
- package/dist/app/process.js +68 -0
- package/dist/app/rendering/conversation-entry-renderer.js +8 -6
- package/dist/app/rendering/conversation-tool-renderer.js +3 -2
- package/dist/app/rendering/editor-layout-renderer.d.ts +1 -0
- package/dist/app/rendering/editor-layout-renderer.js +11 -1
- package/dist/app/rendering/message-content.js +65 -7
- package/dist/app/rendering/render-controller.js +6 -1
- package/dist/app/rendering/render-text.d.ts +3 -0
- package/dist/app/rendering/render-text.js +51 -3
- package/dist/app/rendering/status-line-renderer.d.ts +5 -1
- package/dist/app/rendering/status-line-renderer.js +61 -25
- package/dist/app/rendering/toast-renderer.js +10 -13
- package/dist/app/rendering/tool-block-renderer.d.ts +1 -0
- package/dist/app/rendering/tool-block-renderer.js +16 -33
- package/dist/app/runtime.d.ts +6 -1
- package/dist/app/runtime.js +35 -2
- package/dist/app/screen/clipboard.d.ts +11 -2
- package/dist/app/screen/clipboard.js +29 -21
- package/dist/app/screen/file-link-opener.d.ts +8 -0
- package/dist/app/screen/file-link-opener.js +11 -3
- package/dist/app/screen/file-links.js +3 -3
- package/dist/app/screen/image-opener.d.ts +12 -0
- package/dist/app/screen/image-opener.js +13 -5
- package/dist/app/screen/mouse-controller.d.ts +5 -2
- package/dist/app/screen/mouse-controller.js +16 -1
- package/dist/app/screen/screen-styler.d.ts +4 -1
- package/dist/app/screen/screen-styler.js +3 -2
- package/dist/app/screen/status-controller.d.ts +3 -0
- package/dist/app/screen/status-controller.js +23 -8
- package/dist/app/session/queued-message-controller.d.ts +7 -1
- package/dist/app/session/queued-message-controller.js +36 -21
- package/dist/app/session/resume-session-loader.d.ts +15 -0
- package/dist/app/session/resume-session-loader.js +204 -0
- package/dist/app/session/session-event-controller.d.ts +5 -1
- package/dist/app/session/session-event-controller.js +72 -5
- package/dist/app/session/session-history.js +4 -3
- package/dist/app/session/session-lifecycle-controller.d.ts +5 -0
- package/dist/app/session/session-lifecycle-controller.js +9 -1
- package/dist/app/session/tabs-controller.d.ts +10 -1
- package/dist/app/session/tabs-controller.js +101 -5
- package/dist/app/terminal/nerd-font-controller.d.ts +16 -0
- package/dist/app/terminal/nerd-font-controller.js +30 -23
- package/dist/app/terminal/terminal-controller.d.ts +1 -0
- package/dist/app/terminal/terminal-controller.js +1 -0
- package/dist/app/types.d.ts +14 -0
- package/dist/app/workspace/workspace-actions-controller.d.ts +1 -1
- package/dist/app/workspace/workspace-actions-controller.js +3 -3
- package/dist/app/workspace/workspace-undo.d.ts +1 -1
- package/dist/app/workspace/workspace-undo.js +22 -20
- package/dist/config.d.ts +27 -0
- package/dist/config.js +174 -1
- package/dist/default-pix-config.js +39 -353
- package/dist/input-editor.d.ts +7 -1
- package/dist/input-editor.js +47 -6
- package/dist/markdown-format.d.ts +1 -0
- package/dist/markdown-format.js +26 -1
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.js +5 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +177 -0
- package/dist/schemas/pi-tools-suite-schema.js +218 -0
- package/dist/schemas/pix-schema.d.ts +65 -0
- package/dist/schemas/pix-schema.js +91 -0
- package/dist/terminal-width.js +73 -56
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +3 -0
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +1 -0
- package/external/pi-tools-suite/src/dcp/prompts.ts +1 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +46 -195
- package/external/pi-tools-suite/src/lib/lsp.ts +2 -1
- package/external/pi-tools-suite/src/lsp/_shared/output.ts +8 -7
- package/external/pi-tools-suite/src/lsp/manager.ts +4 -4
- package/external/pi-tools-suite/src/repo-discovery/index.ts +49 -2
- package/external/pi-tools-suite/src/todo/index.ts +4 -2
- package/external/pi-tools-suite/src/todo/state/selectors.ts +4 -0
- package/external/pi-tools-suite/src/todo/todo.ts +2 -6
- package/external/pi-tools-suite/src/todo/tool/response-envelope.ts +9 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +1 -1
- package/package.json +12 -3
- package/schemas/pi-tools-suite.json +881 -0
- package/schemas/pix.json +298 -0
|
@@ -4,6 +4,7 @@ import type { CommandRunResult } from "./types";
|
|
|
4
4
|
import { normalizeRelativePath, uriToFilePath } from "./paths";
|
|
5
5
|
|
|
6
6
|
const DEFAULT_OUTPUT_LIMIT = 4000;
|
|
7
|
+
export const LSP_DIAGNOSTIC_ICON = "\u{f0026}";
|
|
7
8
|
|
|
8
9
|
export function textFromContent(content: Array<{ type: string; text?: string }>): string {
|
|
9
10
|
return content
|
|
@@ -29,20 +30,20 @@ export function commandOutput(result: Pick<CommandRunResult, "stdout" | "stderr"
|
|
|
29
30
|
|
|
30
31
|
export function formatWarnings(title: string, warnings: string[]): string {
|
|
31
32
|
if (warnings.length === 0) return "";
|
|
32
|
-
return `${title}:\n\n${warnings.map((warning) =>
|
|
33
|
+
return `${title}:\n\n${warnings.map((warning) => `${LSP_DIAGNOSTIC_ICON} ${warning}`).join("\n")}`;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
export function formatCommandIssue(toolId: string, action: string, result: CommandRunResult): string {
|
|
36
37
|
const output = commandOutput(result);
|
|
37
38
|
const suffix = result.killed ? " (killed/timeout)" : "";
|
|
38
|
-
if (!output) return
|
|
39
|
-
return
|
|
39
|
+
if (!output) return `${LSP_DIAGNOSTIC_ICON} ${toolId} ${action} failed with exit code ${result.code}${suffix}`;
|
|
40
|
+
return `${LSP_DIAGNOSTIC_ICON} ${toolId} ${action} failed with exit code ${result.code}${suffix}:\n${output}`;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export function formatDiagnosticOutput(toolId: string, output: string): string {
|
|
43
44
|
const compact = truncateOutput(output);
|
|
44
|
-
if (!compact) return
|
|
45
|
-
return
|
|
45
|
+
if (!compact) return `${LSP_DIAGNOSTIC_ICON} ${toolId} found issues`;
|
|
46
|
+
return `${LSP_DIAGNOSTIC_ICON} ${toolId} found issues:\n${compact}`;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
function severityLabel(severity: number | undefined): string {
|
|
@@ -88,11 +89,11 @@ export function formatLspDiagnostics(serverId: string, file: string, diagnostics
|
|
|
88
89
|
if (diagnostics.length === 0) return "";
|
|
89
90
|
const rendered = diagnostics.slice(0, 20).map((diagnostic) => formatDiagnostic(file, diagnostic, root));
|
|
90
91
|
if (diagnostics.length > 20) rendered.push(`… ${diagnostics.length - 20} more diagnostics`);
|
|
91
|
-
return
|
|
92
|
+
return `${LSP_DIAGNOSTIC_ICON} ${serverId}:\n${rendered.join("\n")}`;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
export function hasIssueOutput(output: string): boolean {
|
|
95
|
-
return output.includes("⚠️");
|
|
96
|
+
return output.includes(LSP_DIAGNOSTIC_ICON) || output.includes("⚠️") || output.includes("⚠");
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
export function joinSections(title: string, lines: string[]): string {
|
|
@@ -6,7 +6,7 @@ import { LspClient } from "./client";
|
|
|
6
6
|
import { loadLspConfig } from "./_shared/config";
|
|
7
7
|
import { isPathIncluded } from "./_shared/glob";
|
|
8
8
|
import { filePathToUri, findProjectRoot, normalizeRelativePath, resolveCommand, toAbsolutePath } from "./_shared/paths";
|
|
9
|
-
import { formatLspDiagnostics, formatWarnings, joinSections } from "./_shared/output";
|
|
9
|
+
import { formatLspDiagnostics, formatWarnings, joinSections, LSP_DIAGNOSTIC_ICON } from "./_shared/output";
|
|
10
10
|
import type { LspServerConfig, StoredDiagnostics } from "./_shared/types";
|
|
11
11
|
import { clientKey, couldMatchBeforeRoot, fileSizeAllowed, languageIdForFile, readTextFile } from "./lsp-utils";
|
|
12
12
|
import { localMarkdownDiagnostics } from "./markdown-diagnostics";
|
|
@@ -112,7 +112,7 @@ export class LspManager {
|
|
|
112
112
|
try {
|
|
113
113
|
const maxFileSizeBytes = match.server.maxFileSizeBytes ?? DEFAULT_MAX_FILE_SIZE_BYTES;
|
|
114
114
|
if (!(await fileSizeAllowed(file, maxFileSizeBytes))) {
|
|
115
|
-
lines.push(
|
|
115
|
+
lines.push(`${LSP_DIAGNOSTIC_ICON} ${match.server.id}: skipped ${match.relFile}; file exceeds maxFileSizeBytes (${maxFileSizeBytes})`);
|
|
116
116
|
continue;
|
|
117
117
|
}
|
|
118
118
|
|
|
@@ -173,14 +173,14 @@ export class LspManager {
|
|
|
173
173
|
if (!isFreshDiagnosticsEntry(entry, startedAt, doc.version)) {
|
|
174
174
|
const fallbackSuffix = tsserverFallbackError ? `; tsserver fallback failed: ${tsserverFallbackError}` : "";
|
|
175
175
|
const pullSuffix = pullDiagnosticsError ? `; pull diagnostics failed: ${pullDiagnosticsError}` : "";
|
|
176
|
-
lines.push(
|
|
176
|
+
lines.push(`${LSP_DIAGNOSTIC_ICON} ${match.server.id}: timed out after ${diagnosticsWaitMs}ms waiting for fresh diagnostics for ${match.relFile}${fallbackSuffix}${pullSuffix}`);
|
|
177
177
|
continue;
|
|
178
178
|
}
|
|
179
179
|
const diagnostics = diagnosticsWithLocalFallback(match.server.id, file, text, entry.diagnostics);
|
|
180
180
|
if (diagnostics !== entry.diagnostics) this.diagnostics.set(match.server.id, match.root, filePathToUri(file), diagnostics, doc.version);
|
|
181
181
|
lines.push(formatLspDiagnostics(match.server.id, file, diagnostics, match.root));
|
|
182
182
|
} catch (error) {
|
|
183
|
-
lines.push(
|
|
183
|
+
lines.push(`${LSP_DIAGNOSTIC_ICON} ${match.server.id}: ${(error as Error).message}`);
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -112,9 +112,56 @@ async function initializeIndexedProject(pi: ExtensionAPI, cwd: string, signal: A
|
|
|
112
112
|
const indexerDir = path.join(projectRoot, ".indexer-cli");
|
|
113
113
|
if (directoryExists(indexerDir)) return { projectRoot, initialized: false, alreadyIndexed: true, output: "Project is already indexed." };
|
|
114
114
|
|
|
115
|
+
const idxCli = await ensureIdxCliAvailable(pi, projectRoot, signal);
|
|
116
|
+
if (!idxCli.available) {
|
|
117
|
+
return {
|
|
118
|
+
projectRoot,
|
|
119
|
+
initialized: false,
|
|
120
|
+
alreadyIndexed: false,
|
|
121
|
+
output: idxCli.output,
|
|
122
|
+
exitCode: idxCli.exitCode,
|
|
123
|
+
installedIdx: idxCli.installed,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
115
127
|
const init = await pi.exec("idx", ["init"], { cwd: projectRoot, signal, timeout: 600_000 });
|
|
116
|
-
const
|
|
117
|
-
|
|
128
|
+
const initOutput = [init.stdout, init.stderr].filter(Boolean).join(init.stdout && init.stderr ? "\n" : "").trim() || "No output";
|
|
129
|
+
const output = idxCli.installed
|
|
130
|
+
? [`idx was not available; installed with npm install -g indexer-cli@latest:`, idxCli.output, `idx init output:`, initOutput].join("\n\n")
|
|
131
|
+
: initOutput;
|
|
132
|
+
return { projectRoot, initialized: (init.code ?? 0) === 0, alreadyIndexed: false, output, exitCode: init.code ?? 0, installedIdx: idxCli.installed };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function ensureIdxCliAvailable(pi: ExtensionAPI, cwd: string, signal: AbortSignal | undefined) {
|
|
136
|
+
const check = await runCommandSafely(pi, "sh", ["-lc", "command -v idx"], { cwd, signal, timeout: 30_000 });
|
|
137
|
+
if ((check.code ?? 0) === 0) return { available: true, installed: false, output: "idx is available.", exitCode: 0 };
|
|
138
|
+
|
|
139
|
+
const install = await runCommandSafely(pi, "npm", ["install", "-g", "indexer-cli@latest"], { cwd, signal, timeout: 600_000 });
|
|
140
|
+
const installOutput = [install.stdout, install.stderr].filter(Boolean).join(install.stdout && install.stderr ? "\n" : "").trim() || "No output";
|
|
141
|
+
const exitCode = install.code ?? 0;
|
|
142
|
+
if (exitCode !== 0) {
|
|
143
|
+
return {
|
|
144
|
+
available: false,
|
|
145
|
+
installed: false,
|
|
146
|
+
output: [`idx is not available and npm install -g indexer-cli@latest failed:`, installOutput].join("\n\n"),
|
|
147
|
+
exitCode,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return { available: true, installed: true, output: installOutput, exitCode };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function runCommandSafely(
|
|
155
|
+
pi: ExtensionAPI,
|
|
156
|
+
command: string,
|
|
157
|
+
args: string[],
|
|
158
|
+
options: { cwd?: string; signal?: AbortSignal; timeout?: number },
|
|
159
|
+
): Promise<ExecResult> {
|
|
160
|
+
try {
|
|
161
|
+
return await pi.exec(command, args, options);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), code: 1 };
|
|
164
|
+
}
|
|
118
165
|
}
|
|
119
166
|
|
|
120
167
|
async function updateIndexerCli(pi: ExtensionAPI, cwd: string, signal: AbortSignal | undefined) {
|
|
@@ -2,7 +2,7 @@ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-a
|
|
|
2
2
|
import { autoClearCompletedTodos } from "./state/auto-clear.js";
|
|
3
3
|
import { loadPersistedPlan, syncPersistedPlan } from "./state/persistence.js";
|
|
4
4
|
import { replayFromBranch } from "./state/replay.js";
|
|
5
|
-
import { ACTIVE_STATUSES, selectVisibleTasks } from "./state/selectors.js";
|
|
5
|
+
import { ACTIVE_STATUSES, isTaskBlocked, selectVisibleTasks } from "./state/selectors.js";
|
|
6
6
|
import { getState, replaceState } from "./state/store.js";
|
|
7
7
|
import { publishTodoState, registerTodosCommand, registerTodoTool } from "./todo.js";
|
|
8
8
|
|
|
@@ -17,7 +17,9 @@ function isAskUserToolName(toolName: string): boolean {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function getUnfinishedTodoNudge(): { signature: string; message: string } | undefined {
|
|
20
|
-
const
|
|
20
|
+
const visible = selectVisibleTasks(getState());
|
|
21
|
+
const byId = new Map(visible.map((task) => [task.id, task]));
|
|
22
|
+
const unfinished = visible.filter((task) => ACTIVE_STATUSES.has(task.status) && !isTaskBlocked(task, byId));
|
|
21
23
|
if (unfinished.length === 0) return undefined;
|
|
22
24
|
|
|
23
25
|
const signature = JSON.stringify(
|
|
@@ -47,3 +47,7 @@ export function selectTodoCounts(state: TaskState): TodoCounts {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export const ACTIVE_STATUSES: ReadonlySet<TaskStatus> = new Set(["pending", "in_progress"]);
|
|
50
|
+
|
|
51
|
+
export function isTaskBlocked(task: Task, byId: ReadonlyMap<number, Task>): boolean {
|
|
52
|
+
return (task.blockedBy ?? []).some((id) => byId.get(id)?.status !== "completed");
|
|
53
|
+
}
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
} from "./state/persistence.js";
|
|
24
24
|
import { AUTO_CLEAR_COMPLETED_MESSAGE, autoClearCompletedTodos } from "./state/auto-clear.js";
|
|
25
25
|
import { replayFromBranch } from "./state/replay.js";
|
|
26
|
-
import { selectTasksByStatus, selectTodoCounts } from "./state/selectors.js";
|
|
26
|
+
import { isTaskBlocked, selectTasksByStatus, selectTodoCounts } from "./state/selectors.js";
|
|
27
27
|
import { applyTaskMutation } from "./state/state-reducer.js";
|
|
28
28
|
import { commitState, getState, replaceState } from "./state/store.js";
|
|
29
29
|
import { buildToolResult, formatContent } from "./tool/response-envelope.js";
|
|
@@ -287,11 +287,7 @@ function filterCommandTasks(tasks: readonly Task[], options: TodosCommandOptions
|
|
|
287
287
|
if (!options.includeDeleted) view = view.filter((task) => task.status !== "deleted");
|
|
288
288
|
if (options.activeOnly) view = view.filter((task) => task.status === "pending" || task.status === "in_progress");
|
|
289
289
|
if (options.readyOnly) {
|
|
290
|
-
view = view.filter(
|
|
291
|
-
(task) =>
|
|
292
|
-
task.status === "pending" &&
|
|
293
|
-
(task.blockedBy ?? []).every((id) => byId.get(id)?.status === "completed"),
|
|
294
|
-
);
|
|
290
|
+
view = view.filter((task) => task.status === "pending" && !isTaskBlocked(task, byId));
|
|
295
291
|
}
|
|
296
292
|
if (options.status) view = view.filter((task) => task.status === options.status);
|
|
297
293
|
if (options.priority) view = view.filter((task) => task.priority === options.priority);
|
|
@@ -131,7 +131,7 @@ export function buildToolResult(
|
|
|
131
131
|
state: TaskState,
|
|
132
132
|
op: Op,
|
|
133
133
|
): { content: Array<{ type: "text"; text: string }>; details: TaskDetails } {
|
|
134
|
-
const text = formatContent(op, state);
|
|
134
|
+
const text = appendWorkflowReminder(formatContent(op, state), op, state);
|
|
135
135
|
const details: TaskDetails = {
|
|
136
136
|
action,
|
|
137
137
|
params: params as Record<string, unknown>,
|
|
@@ -141,3 +141,11 @@ export function buildToolResult(
|
|
|
141
141
|
};
|
|
142
142
|
return { content: [{ type: "text", text }], details };
|
|
143
143
|
}
|
|
144
|
+
|
|
145
|
+
function appendWorkflowReminder(text: string, op: Op, state: TaskState): string {
|
|
146
|
+
if (op.kind === "error" || op.kind === "export") return text;
|
|
147
|
+
const hasPending = state.tasks.some((task) => task.status === "pending");
|
|
148
|
+
const hasInProgress = state.tasks.some((task) => task.status === "in_progress");
|
|
149
|
+
if (!hasPending || hasInProgress) return text;
|
|
150
|
+
return `${text}\n\nReminder: pending todos exist but none is in_progress. Before starting work, call todo update on exactly one task with status in_progress and activeForm.`;
|
|
151
|
+
}
|
|
@@ -256,7 +256,7 @@ export const TODO_TOOL_DESCRIPTION: ToolDescription = {
|
|
|
256
256
|
"When the user adds, removes, cancels, reprioritizes, or changes the goal, scope, requirements, constraints, or chosen approach, use `todo` before continuing to synchronize the plan: update still-relevant tasks, defer or delete obsolete tasks, add new required tasks, and adjust dependencies/order.",
|
|
257
257
|
"When your own investigation or verification discovers new facts that make the current todo plan stale, incomplete, impossible, unsafe, or no longer the best approach, use `todo` to revise the plan immediately instead of following outdated tasks.",
|
|
258
258
|
"Update todos as part of the workflow, not as end-of-task cleanup: whenever you start, finish, block, split, abandon, or materially change a step, call `todo` immediately before continuing.",
|
|
259
|
-
"Before
|
|
259
|
+
"Before any non-trivial read/edit/test/tool work on a planned task, mark exactly one task in_progress with activeForm (present-continuous label); do this immediately after creating a plan if no task is active. Mark it completed immediately after the required verification, never in batches.",
|
|
260
260
|
"If implementation is partial, tests fail, or a blocker remains, keep the task in_progress and add/update a blocker task instead of completing it.",
|
|
261
261
|
"Never use `clear`, `delete`, or batch deletion to hide unfinished, stale, or forgotten todos. Defer obsolete items or update them with the reason; only delete when the user explicitly asks or the item was created by mistake.",
|
|
262
262
|
"Before giving a final response for work that used todos, ensure every visible todo is completed, deferred, or intentionally still in_progress with a blocker/explanation.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-ui-extend",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,13 +14,16 @@
|
|
|
14
14
|
"./sdk": {
|
|
15
15
|
"types": "./dist/sdk.d.ts",
|
|
16
16
|
"import": "./dist/sdk.js"
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
|
+
"./schemas/pix.json": "./schemas/pix.json",
|
|
19
|
+
"./schemas/pi-tools-suite.json": "./schemas/pi-tools-suite.json"
|
|
18
20
|
},
|
|
19
21
|
"files": [
|
|
20
22
|
"bin",
|
|
21
23
|
"docs",
|
|
22
24
|
"dist",
|
|
23
25
|
"extensions",
|
|
26
|
+
"schemas",
|
|
24
27
|
"skills",
|
|
25
28
|
"external/pi-tools-suite/index.ts",
|
|
26
29
|
"external/pi-tools-suite/package.json",
|
|
@@ -34,22 +37,28 @@
|
|
|
34
37
|
"predev": "npm run link:pix --silent",
|
|
35
38
|
"dev": "mise exec node@24.16.0 -- tsx src/main.ts",
|
|
36
39
|
"start": "mise exec node@24.16.0 -- tsx src/main.ts",
|
|
40
|
+
"prebuild:pix": "npm run generate-schemas --silent",
|
|
37
41
|
"build:pix": "mise exec node@24.16.0 -- tsc -p tsconfig.json",
|
|
38
42
|
"prelink:pix": "npm run build:pix --silent",
|
|
39
43
|
"link:pix": "mise exec node@24.16.0 -- npm link --silent",
|
|
40
44
|
"watch:pix": "npm run link:pix --silent && mise exec node@24.16.0 -- tsc -p tsconfig.json --watch --preserveWatchOutput --noEmitOnError",
|
|
41
45
|
"check": "mise exec node@24.16.0 -- npm run check:inner",
|
|
46
|
+
"precheck:inner": "npm run generate-schemas --silent",
|
|
42
47
|
"check:inner": "tsc --noEmit && npm run test:inner",
|
|
43
48
|
"test": "mise exec node@24.16.0 -- npm run test:inner",
|
|
44
49
|
"test:inner": "node --import tsx --test \"tests/**/*.test.ts\"",
|
|
45
50
|
"test:tools-suite": "npm --prefix external/pi-tools-suite test",
|
|
46
51
|
"test:coverage": "mise exec node@24.16.0 -- node --import tsx --test --experimental-test-coverage --test-coverage-include=src/**/*.ts --test-coverage-exclude=src/main.ts --test-coverage-lines=95 --test-coverage-branches=80 --test-coverage-functions=95 \"tests/**/*.test.ts\"",
|
|
47
52
|
"update-sdk-references": "mise exec node@24.16.0 -- node .pi/skills/pi-sdk/scripts/update-references.mjs",
|
|
53
|
+
"prepack": "npm run generate-schemas --silent",
|
|
48
54
|
"pack:dry-run": "npm pack --dry-run",
|
|
49
55
|
"smoke-test": "mise exec node@24.16.0 -- bash scripts/smoke-test-package.sh",
|
|
50
56
|
"release:check": "npm run check && npm run build:pix && npm run pack:dry-run",
|
|
51
57
|
"publish-npm": "bash scripts/publish.sh",
|
|
52
|
-
"
|
|
58
|
+
"generate-schemas": "tsx scripts/generate-schemas.ts",
|
|
59
|
+
"generate-schemas:check": "tsx scripts/generate-schemas.ts --check",
|
|
60
|
+
"generate-schemas:watch": "tsx watch scripts/generate-schemas.ts",
|
|
61
|
+
"prepublishOnly": "npm run check && npm run build:pix && npm run generate-schemas"
|
|
53
62
|
},
|
|
54
63
|
"dependencies": {
|
|
55
64
|
"@earendil-works/pi-tui": "0.77.0",
|