pi-ui-extend 1.0.41 → 1.0.45
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 +50 -13
- package/dist/app/app.d.ts +13 -0
- package/dist/app/app.js +158 -8
- package/dist/app/cli/install.js +2 -2
- package/dist/app/commands/command-controller.d.ts +4 -0
- package/dist/app/commands/command-controller.js +11 -0
- package/dist/app/commands/command-git-actions.d.ts +25 -0
- package/dist/app/commands/command-git-actions.js +381 -0
- package/dist/app/commands/command-host.d.ts +4 -0
- package/dist/app/commands/command-host.js +5 -2
- package/dist/app/commands/command-model-actions.d.ts +1 -0
- package/dist/app/commands/command-model-actions.js +57 -35
- package/dist/app/commands/command-navigation-actions.d.ts +1 -0
- package/dist/app/commands/command-navigation-actions.js +16 -3
- package/dist/app/commands/command-registry.d.ts +2 -0
- package/dist/app/commands/command-registry.js +15 -1
- package/dist/app/commands/command-session-actions.js +9 -3
- package/dist/app/commands/reload-context-inventory.d.ts +11 -0
- package/dist/app/commands/reload-context-inventory.js +70 -0
- package/dist/app/extensions/extension-actions-controller.d.ts +1 -0
- package/dist/app/extensions/extension-actions-controller.js +6 -0
- package/dist/app/extensions/subagent-catalog-state.d.ts +9 -0
- package/dist/app/extensions/subagent-catalog-state.js +23 -0
- package/dist/app/input/autocomplete-controller.js +61 -34
- package/dist/app/input/input-action-controller.d.ts +2 -0
- package/dist/app/input/input-action-controller.js +8 -1
- package/dist/app/input/input-controller.d.ts +2 -1
- package/dist/app/input/input-controller.js +7 -2
- package/dist/app/input/prompt-enhancer-controller.js +53 -35
- package/dist/app/input/voice-controller.d.ts +41 -45
- package/dist/app/input/voice-controller.js +351 -419
- package/dist/app/model/model-usage-controller.js +17 -7
- package/dist/app/model/model-usage-status.d.ts +4 -1
- package/dist/app/model/model-usage-status.js +270 -46
- package/dist/app/popup/menu-items-controller.d.ts +13 -3
- package/dist/app/popup/menu-items-controller.js +37 -21
- package/dist/app/popup/popup-action-controller.d.ts +12 -2
- package/dist/app/popup/popup-action-controller.js +77 -24
- package/dist/app/popup/popup-menu-controller.d.ts +36 -14
- package/dist/app/popup/popup-menu-controller.js +239 -69
- package/dist/app/rendering/dcp-stats.d.ts +9 -4
- package/dist/app/rendering/dcp-stats.js +40 -425
- package/dist/app/rendering/editor-panels.js +10 -4
- package/dist/app/rendering/popup-menu-renderer.d.ts +3 -5
- package/dist/app/rendering/popup-menu-renderer.js +42 -37
- package/dist/app/rendering/render-controller.js +23 -2
- package/dist/app/rendering/status-line-renderer.d.ts +5 -0
- package/dist/app/rendering/status-line-renderer.js +41 -5
- package/dist/app/rendering/tab-line-renderer.js +26 -20
- package/dist/app/runtime.d.ts +12 -1
- package/dist/app/runtime.js +120 -12
- package/dist/app/screen/mouse-controller.d.ts +2 -0
- package/dist/app/screen/mouse-controller.js +17 -7
- package/dist/app/screen/status-controller.d.ts +4 -0
- package/dist/app/screen/status-controller.js +5 -0
- package/dist/app/session/lazy-session-manager.js +34 -0
- package/dist/app/session/session-event-controller.d.ts +1 -0
- package/dist/app/session/session-event-controller.js +10 -1
- package/dist/app/session/session-history.d.ts +1 -0
- package/dist/app/session/session-history.js +12 -1
- package/dist/app/session/session-lifecycle-controller.d.ts +7 -1
- package/dist/app/session/session-lifecycle-controller.js +16 -1
- package/dist/app/session/tabs-controller.d.ts +26 -1
- package/dist/app/session/tabs-controller.js +454 -147
- package/dist/app/subagents/subagents-files.js +60 -1
- package/dist/app/subagents/subagents-model.d.ts +1 -0
- package/dist/app/subagents/subagents-model.js +18 -2
- package/dist/app/subagents/subagents-widget-controller.d.ts +1 -0
- package/dist/app/subagents/subagents-widget-controller.js +6 -0
- package/dist/app/types.d.ts +16 -1
- package/dist/app/workspace/workspace-actions-controller.js +10 -2
- package/dist/app/workspace/workspace-undo.d.ts +1 -0
- package/dist/app/workspace/workspace-undo.js +1 -0
- package/dist/bundled-extensions/question/index.js +9 -1
- package/dist/bundled-extensions/question/remote.d.ts +4 -0
- package/dist/bundled-extensions/question/remote.js +33 -0
- package/dist/bundled-extensions/telegram-connector/bot.d.ts +43 -0
- package/dist/bundled-extensions/telegram-connector/bot.js +166 -0
- package/dist/bundled-extensions/telegram-connector/config.d.ts +8 -0
- package/dist/bundled-extensions/telegram-connector/config.js +87 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.d.ts +66 -0
- package/dist/bundled-extensions/telegram-connector/coordinator.js +413 -0
- package/dist/bundled-extensions/telegram-connector/index.d.ts +3 -0
- package/dist/bundled-extensions/telegram-connector/index.js +195 -0
- package/dist/bundled-extensions/terminal-bell/index.d.ts +0 -8
- package/dist/bundled-extensions/terminal-bell/index.js +0 -76
- package/dist/bundled-extensions/workspace-undo/index.d.ts +26 -0
- package/dist/bundled-extensions/workspace-undo/index.js +191 -0
- package/dist/config.d.ts +21 -2
- package/dist/config.js +159 -32
- package/dist/default-pix-config.js +25 -5
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/pi-tools-suite-schema.d.ts +88 -62
- package/dist/schemas/pi-tools-suite-schema.js +54 -83
- package/dist/schemas/pix-schema.d.ts +19 -2
- package/dist/schemas/pix-schema.js +47 -5
- package/dist/schemas/tasks-schema.d.ts +18 -0
- package/dist/schemas/tasks-schema.js +41 -0
- package/docs/concurrency.md +9 -1
- package/docs/desktop-mvp.md +22 -6
- package/docs/desktop-task-manager.md +148 -84
- package/docs/release.md +30 -6
- package/external/pi-tools-suite/README.md +197 -84
- package/external/pi-tools-suite/docs/evals.md +1 -1
- package/external/pi-tools-suite/docs/session-recovery.md +47 -14
- package/external/pi-tools-suite/docs/subagent-model-pools.md +48 -30
- package/external/pi-tools-suite/docs/ui-qa-subagent.md +440 -0
- package/external/pi-tools-suite/package.json +6 -1
- package/external/pi-tools-suite/src/antigravity-auth/auth-store.ts +2 -1
- package/external/pi-tools-suite/src/antigravity-auth/constants.ts +9 -3
- package/external/pi-tools-suite/src/antigravity-auth/headers.ts +41 -3
- package/external/pi-tools-suite/src/antigravity-auth/models.ts +94 -21
- package/external/pi-tools-suite/src/antigravity-auth/oauth.ts +5 -17
- package/external/pi-tools-suite/src/antigravity-auth/payload.ts +72 -7
- package/external/pi-tools-suite/src/antigravity-auth/stream.ts +13 -1
- package/external/pi-tools-suite/src/async-subagents/agents/frontier-review.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/implement.md +1 -1
- package/external/pi-tools-suite/src/async-subagents/agents/presets.jsonc +16 -0
- package/external/pi-tools-suite/src/async-subagents/agents/research.md +5 -3
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/browser.mjs +346 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/desktop.mjs +1038 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/backends/tui.mjs +759 -0
- package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/scripts/browser-qa-runner.mjs +32 -23
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/chrome-devtools/chrome-devtools-provider.mjs +895 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/linux/linux-atspi.py +494 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/macos/macos-accessibility.swift +1085 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/bridge-client.mjs +50 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/native-terminal/native-terminal-host.mjs +501 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/drivers/windows/windows-uia.ps1 +454 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-auth.md +114 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-chrome-devtools.md +91 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser-playwright.md +145 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/browser.md +82 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-linux.md +26 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-macos.md +29 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop-windows.md +23 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/desktop.md +54 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-native-terminal.md +59 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui-pty.md +37 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/guides/tui.md +60 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa/scripts/ui-qa-runner.mjs +535 -0
- package/external/pi-tools-suite/src/async-subagents/agents/ui-qa.md +75 -0
- package/external/pi-tools-suite/src/async-subagents/commands.ts +15 -71
- package/external/pi-tools-suite/src/async-subagents/core/activity.ts +33 -0
- package/external/pi-tools-suite/src/async-subagents/core/agent-catalog.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +1 -1
- package/external/pi-tools-suite/src/async-subagents/core/agents-dir.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/core/browser-qa.ts +16 -2
- package/external/pi-tools-suite/src/async-subagents/core/config.ts +160 -327
- package/external/pi-tools-suite/src/async-subagents/core/model-selection.ts +2 -1
- package/external/pi-tools-suite/src/async-subagents/core/registry.ts +158 -33
- package/external/pi-tools-suite/src/async-subagents/core/routing.ts +21 -5
- package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +40 -26
- package/external/pi-tools-suite/src/async-subagents/core/state.ts +40 -0
- package/external/pi-tools-suite/src/async-subagents/core/types.ts +7 -0
- package/external/pi-tools-suite/src/async-subagents/core/ultrawork-auto.ts +51 -45
- package/external/pi-tools-suite/src/async-subagents/index.ts +69 -5
- package/external/pi-tools-suite/src/async-subagents/lib.ts +16 -9
- package/external/pi-tools-suite/src/async-subagents/tools/spawn.ts +8 -5
- package/external/pi-tools-suite/src/async-subagents/tools/subagents.ts +5 -4
- package/external/pi-tools-suite/src/async-subagents/types.ts +1 -0
- package/external/pi-tools-suite/src/coding-discipline/index.ts +90 -59
- package/external/pi-tools-suite/src/config.ts +55 -1
- package/external/pi-tools-suite/src/context-gateway/accounting-log.ts +282 -0
- package/external/pi-tools-suite/src/context-gateway/config.ts +77 -3
- package/external/pi-tools-suite/src/context-gateway/efficiency.ts +414 -0
- package/external/pi-tools-suite/src/context-gateway/enforcement.ts +222 -0
- package/external/pi-tools-suite/src/context-gateway/index.ts +206 -19
- package/external/pi-tools-suite/src/context-gateway/storeless-capabilities.ts +7 -7
- package/external/pi-tools-suite/src/context-gateway/telemetry.ts +101 -28
- package/external/pi-tools-suite/src/context-gateway/types.ts +16 -3
- package/external/pi-tools-suite/src/context-inventory.ts +99 -0
- package/external/pi-tools-suite/src/dcp/auto-compress-budget.ts +39 -4
- package/external/pi-tools-suite/src/dcp/auto-compress.ts +128 -49
- package/external/pi-tools-suite/src/dcp/commands.ts +32 -156
- package/external/pi-tools-suite/src/dcp/compress-tool.ts +177 -46
- package/external/pi-tools-suite/src/dcp/compression-blocks.ts +6 -58
- package/external/pi-tools-suite/src/dcp/compression-preview.ts +9 -0
- package/external/pi-tools-suite/src/dcp/compression-progress.ts +22 -0
- package/external/pi-tools-suite/src/dcp/config.ts +114 -17
- package/external/pi-tools-suite/src/dcp/conversation-index.ts +36 -9
- package/external/pi-tools-suite/src/dcp/diagnostics.ts +41 -0
- package/external/pi-tools-suite/src/dcp/fresh-tool-results.ts +38 -0
- package/external/pi-tools-suite/src/dcp/index.ts +338 -66
- package/external/pi-tools-suite/src/dcp/journal.ts +126 -4
- package/external/pi-tools-suite/src/dcp/progress-controller.ts +2 -1
- package/external/pi-tools-suite/src/dcp/prompts.ts +83 -192
- package/external/pi-tools-suite/src/dcp/protected-continuity.ts +175 -0
- package/external/pi-tools-suite/src/dcp/pruner-candidates.ts +93 -3
- package/external/pi-tools-suite/src/dcp/pruner-message-ids.ts +6 -10
- package/external/pi-tools-suite/src/dcp/pruner-nudge.ts +36 -33
- package/external/pi-tools-suite/src/dcp/pruner-tools.ts +6 -3
- package/external/pi-tools-suite/src/dcp/pruner.ts +1 -0
- package/external/pi-tools-suite/src/dcp/routine-pressure.ts +86 -0
- package/external/pi-tools-suite/src/dcp/state.ts +9 -0
- package/external/pi-tools-suite/src/dcp/statistics.d.ts +8 -0
- package/external/pi-tools-suite/src/dcp/statistics.js +156 -0
- package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +78 -22
- package/external/pi-tools-suite/src/index.ts +7 -1
- package/external/pi-tools-suite/src/lib/project.ts +36 -1
- package/external/pi-tools-suite/src/model-tools/index.ts +10 -7
- package/external/pi-tools-suite/src/repo-discovery/index.ts +304 -4
- package/external/pi-tools-suite/src/resource-registry/index.ts +2551 -0
- package/external/pi-tools-suite/src/session-recovery/index.ts +17 -0
- package/external/pi-tools-suite/src/shell-command-policy.ts +219 -0
- package/external/pi-tools-suite/src/todo/index.ts +21 -0
- package/external/pi-tools-suite/src/todo/todo.ts +19 -1
- package/external/pi-tools-suite/src/tool-descriptions.ts +47 -19
- package/package.json +10 -9
- package/schemas/pi-tools-suite.json +466 -287
- package/schemas/pix.json +129 -11
- package/schemas/tasks.json +131 -0
- package/skills/simplify/SKILL.md +33 -5
- package/docs/desktop-markdown-media.md +0 -77
- package/external/pi-tools-suite/docs/browser-qa-subagent.md +0 -177
- package/external/pi-tools-suite/docs/dcp-emergency-current-turn.md +0 -102
- package/external/pi-tools-suite/src/async-subagents/agents/browser-qa.md +0 -598
- package/external/pi-tools-suite/src/async-subagents/async-subagents.sample.jsonc +0 -54
- package/external/pi-tools-suite/src/skill-installer/index.ts +0 -333
- package/skills/playwright-cli/SKILL.md +0 -420
- package/skills/playwright-cli/references/element-attributes.md +0 -23
- package/skills/playwright-cli/references/playwright-tests.md +0 -50
- package/skills/playwright-cli/references/request-mocking.md +0 -87
- package/skills/playwright-cli/references/running-code.md +0 -241
- package/skills/playwright-cli/references/session-management.md +0 -273
- package/skills/playwright-cli/references/spec-driven-testing.md +0 -311
- package/skills/playwright-cli/references/storage-state.md +0 -290
- package/skills/playwright-cli/references/test-generation.md +0 -142
- package/skills/playwright-cli/references/tracing.md +0 -154
- package/skills/playwright-cli/references/video-recording.md +0 -147
- package/skills/spec-lite/SKILL.md +0 -140
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-auth.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/examples/qa-flow.example.jsonc +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.LICENSE +0 -0
- /package/external/pi-tools-suite/src/async-subagents/agents/{browser-qa → ui-qa/browser}/vendor/fflate.mjs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { REPO_DISCOVERY_TOOLS } from "../tool-descriptions";
|
|
3
|
-
import {
|
|
2
|
+
import { REPO_DISCOVERY_TOOLS, REPO_KNOWLEDGE_TOOL_DESCRIPTION } from "../tool-descriptions";
|
|
3
|
+
import { commandAvailable, directoryExists, findProjectRoot, hasAvailableIndexedProjectRoot } from "../lib/project.js";
|
|
4
4
|
import {
|
|
5
5
|
applyNativeCompactPolicy,
|
|
6
6
|
describeNativeCompactArgs,
|
|
@@ -12,6 +12,21 @@ import {
|
|
|
12
12
|
} from "./native-compact.js";
|
|
13
13
|
|
|
14
14
|
const IDX_COMMANDS = ["architecture", "structure", "ast", "search", "explain", "deps"] as const;
|
|
15
|
+
const REPO_KNOWLEDGE_ACTIONS = [
|
|
16
|
+
"context",
|
|
17
|
+
"search",
|
|
18
|
+
"show",
|
|
19
|
+
"status",
|
|
20
|
+
"audit",
|
|
21
|
+
"discover",
|
|
22
|
+
"impact",
|
|
23
|
+
"catalog",
|
|
24
|
+
"record",
|
|
25
|
+
"verify",
|
|
26
|
+
"relate",
|
|
27
|
+
"remove",
|
|
28
|
+
] as const;
|
|
29
|
+
const REPO_KNOWLEDGE_MUTATING_ACTIONS = new Set<string>(["record", "verify", "relate", "remove"]);
|
|
15
30
|
const TARGET_COMMANDS = new Set<string>(["ast", "search", "explain", "deps"]);
|
|
16
31
|
const DEFAULT_MAX_LINES = 2000;
|
|
17
32
|
const DEFAULT_MAX_BYTES = 50_000;
|
|
@@ -22,6 +37,12 @@ const SYSTEM_CUSTOM_MESSAGE_TYPE = "pix-system";
|
|
|
22
37
|
const idxExecutionQueues = new Map<string, Promise<void>>();
|
|
23
38
|
|
|
24
39
|
type IdxCommand = (typeof IDX_COMMANDS)[number];
|
|
40
|
+
type RepoKnowledgeAction = (typeof REPO_KNOWLEDGE_ACTIONS)[number];
|
|
41
|
+
type KnowledgeClassification = "spec" | "spec-like" | "meta-index" | "design-only" | "guide" | "other";
|
|
42
|
+
type KnowledgeBehaviorType = "as-is" | "change" | "mixed" | "unknown";
|
|
43
|
+
type KnowledgeLifecycle = "active" | "proposed" | "historical" | "superseded" | "unknown";
|
|
44
|
+
type KnowledgeRelationKind = "implements" | "tests" | "related" | "supersedes" | "superseded-by";
|
|
45
|
+
type KnowledgeRelationAction = "add" | "remove";
|
|
25
46
|
|
|
26
47
|
type RepoDiscoveryParams = {
|
|
27
48
|
command: IdxCommand;
|
|
@@ -34,6 +55,39 @@ type RepoDiscoveryParams = {
|
|
|
34
55
|
|
|
35
56
|
type RepoDiscoveryWrapperParams = Omit<RepoDiscoveryParams, "command">;
|
|
36
57
|
|
|
58
|
+
type RepoKnowledgeParams = {
|
|
59
|
+
action: RepoKnowledgeAction;
|
|
60
|
+
query?: string;
|
|
61
|
+
path?: string;
|
|
62
|
+
paths?: string[];
|
|
63
|
+
classification?: KnowledgeClassification;
|
|
64
|
+
behaviorType?: KnowledgeBehaviorType;
|
|
65
|
+
lifecycle?: KnowledgeLifecycle;
|
|
66
|
+
confidence?: "high" | "medium" | "low" | "unknown";
|
|
67
|
+
summary?: string;
|
|
68
|
+
topics?: string[];
|
|
69
|
+
includeSecondary?: boolean;
|
|
70
|
+
pathPrefix?: string;
|
|
71
|
+
limit?: number;
|
|
72
|
+
budget?: number;
|
|
73
|
+
maxSpecs?: number;
|
|
74
|
+
maxCode?: number;
|
|
75
|
+
maxTests?: number;
|
|
76
|
+
includeAll?: boolean;
|
|
77
|
+
allUnclassified?: boolean;
|
|
78
|
+
base?: string;
|
|
79
|
+
semantic?: boolean;
|
|
80
|
+
relationAction?: KnowledgeRelationAction;
|
|
81
|
+
relationKind?: KnowledgeRelationKind;
|
|
82
|
+
targetPaths?: string[];
|
|
83
|
+
sourceReviewed?: boolean;
|
|
84
|
+
evidenceReviewed?: boolean;
|
|
85
|
+
metadataOnlyConfirmed?: boolean;
|
|
86
|
+
maxLines?: number;
|
|
87
|
+
maxBytes?: number;
|
|
88
|
+
outputMode?: RepoDiscoveryOutputMode;
|
|
89
|
+
};
|
|
90
|
+
|
|
37
91
|
type ExecResult = {
|
|
38
92
|
stdout: string;
|
|
39
93
|
stderr: string;
|
|
@@ -108,6 +162,16 @@ function positiveInteger(value: number | undefined, fallback: number): number {
|
|
|
108
162
|
|
|
109
163
|
function ensureIndexedProject(cwd: string, toolName: string) {
|
|
110
164
|
const projectRoot = findProjectRoot(cwd);
|
|
165
|
+
if (!commandAvailable("idx")) {
|
|
166
|
+
return {
|
|
167
|
+
projectRoot,
|
|
168
|
+
error: [
|
|
169
|
+
`${toolName} is unavailable because idx is not on PATH.`,
|
|
170
|
+
"Do not initialize, install, or create project-local index state implicitly.",
|
|
171
|
+
"If the user wants indexed repository tools, ask for explicit permission to run /idx-init, then /reload.",
|
|
172
|
+
].join("\n"),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
111
175
|
const indexerDir = path.join(projectRoot, ".indexer-cli");
|
|
112
176
|
if (directoryExists(indexerDir)) return { projectRoot, initialized: false };
|
|
113
177
|
|
|
@@ -124,7 +188,6 @@ function ensureIndexedProject(cwd: string, toolName: string) {
|
|
|
124
188
|
async function initializeIndexedProject(pi: ExtensionAPI, cwd: string, signal: AbortSignal | undefined) {
|
|
125
189
|
const projectRoot = findProjectRoot(cwd);
|
|
126
190
|
const indexerDir = path.join(projectRoot, ".indexer-cli");
|
|
127
|
-
if (directoryExists(indexerDir)) return { projectRoot, initialized: false, alreadyIndexed: true, output: "Project is already indexed." };
|
|
128
191
|
|
|
129
192
|
const idxCli = await ensureIdxCliAvailable(pi, projectRoot, signal);
|
|
130
193
|
if (!idxCli.available) {
|
|
@@ -137,6 +200,17 @@ async function initializeIndexedProject(pi: ExtensionAPI, cwd: string, signal: A
|
|
|
137
200
|
installedIdx: idxCli.installed,
|
|
138
201
|
};
|
|
139
202
|
}
|
|
203
|
+
if (directoryExists(indexerDir)) {
|
|
204
|
+
return {
|
|
205
|
+
projectRoot,
|
|
206
|
+
initialized: false,
|
|
207
|
+
alreadyIndexed: true,
|
|
208
|
+
output: idxCli.installed
|
|
209
|
+
? `idx was installed and the project is already indexed: ${projectRoot}. Run /reload to expose repo_* tools.`
|
|
210
|
+
: "Project is already indexed.",
|
|
211
|
+
installedIdx: idxCli.installed,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
140
214
|
|
|
141
215
|
const init = await pi.exec("idx", ["init"], { cwd: projectRoot, signal, timeout: 600_000 });
|
|
142
216
|
const initOutput = [init.stdout, init.stderr].filter(Boolean).join(init.stdout && init.stderr ? "\n" : "").trim() || "No output";
|
|
@@ -322,6 +396,159 @@ async function executeRepoDiscovery(
|
|
|
322
396
|
});
|
|
323
397
|
}
|
|
324
398
|
|
|
399
|
+
function nonEmpty(value: unknown): value is string {
|
|
400
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function normalizedStrings(value: unknown): string[] {
|
|
404
|
+
if (!Array.isArray(value)) return [];
|
|
405
|
+
return [...new Set(value.filter((item): item is string => nonEmpty(item)).map((item) => item.trim()))];
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function positiveBounded(value: number | undefined, fallback: number, maximum: number): number {
|
|
409
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) return fallback;
|
|
410
|
+
return Math.min(value, maximum);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function buildRepoKnowledgeArgs(params: RepoKnowledgeParams): string[] | string {
|
|
414
|
+
if (!REPO_KNOWLEDGE_ACTIONS.includes(params.action)) {
|
|
415
|
+
return `Invalid repo_knowledge action. Use one of: ${REPO_KNOWLEDGE_ACTIONS.join(", ")}.`;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const query = params.query?.trim();
|
|
419
|
+
const sourcePath = params.path?.trim();
|
|
420
|
+
const paths = normalizedStrings(params.paths);
|
|
421
|
+
const topics = normalizedStrings(params.topics);
|
|
422
|
+
const targets = normalizedStrings(params.targetPaths);
|
|
423
|
+
|
|
424
|
+
switch (params.action) {
|
|
425
|
+
case "context": {
|
|
426
|
+
if (!query) return "repo_knowledge action=context requires query.";
|
|
427
|
+
const args = [
|
|
428
|
+
"context",
|
|
429
|
+
query,
|
|
430
|
+
"--budget",
|
|
431
|
+
String(positiveBounded(params.budget, 1400, 8000)),
|
|
432
|
+
"--max-specs",
|
|
433
|
+
String(positiveBounded(params.maxSpecs, 4, 20)),
|
|
434
|
+
"--max-code",
|
|
435
|
+
String(positiveBounded(params.maxCode, 6, 30)),
|
|
436
|
+
"--max-tests",
|
|
437
|
+
String(positiveBounded(params.maxTests, 4, 20)),
|
|
438
|
+
];
|
|
439
|
+
if (params.includeSecondary) args.push("--include-secondary");
|
|
440
|
+
if (nonEmpty(params.pathPrefix)) args.push("--path-prefix", params.pathPrefix.trim());
|
|
441
|
+
return args;
|
|
442
|
+
}
|
|
443
|
+
case "search": {
|
|
444
|
+
if (!query) return "repo_knowledge action=search requires query.";
|
|
445
|
+
const args = ["wiki", "search", query, "--limit", String(positiveBounded(params.limit, 5, 20))];
|
|
446
|
+
if (params.includeSecondary) args.push("--include-secondary");
|
|
447
|
+
if (nonEmpty(params.pathPrefix)) args.push("--path-prefix", params.pathPrefix.trim());
|
|
448
|
+
return args;
|
|
449
|
+
}
|
|
450
|
+
case "show":
|
|
451
|
+
return sourcePath ? ["wiki", "show", "--path", sourcePath] : "repo_knowledge action=show requires path.";
|
|
452
|
+
case "status":
|
|
453
|
+
case "audit":
|
|
454
|
+
return ["wiki", params.action, "--candidate-limit", String(positiveBounded(params.limit, 20, 100))];
|
|
455
|
+
case "discover": {
|
|
456
|
+
if (params.includeAll && params.allUnclassified) return "repo_knowledge discover cannot combine includeAll and allUnclassified.";
|
|
457
|
+
const args = ["wiki", "discover", "--limit", String(positiveBounded(params.limit, 40, 200))];
|
|
458
|
+
if (params.includeAll) args.push("--all");
|
|
459
|
+
if (params.allUnclassified) args.push("--all-unclassified");
|
|
460
|
+
return args;
|
|
461
|
+
}
|
|
462
|
+
case "impact": {
|
|
463
|
+
const args = ["wiki", "impact", ...paths];
|
|
464
|
+
if (nonEmpty(params.base)) args.push("--base", params.base.trim());
|
|
465
|
+
args.push("--semantic-limit", String(positiveBounded(params.limit, 5, 20)));
|
|
466
|
+
if (params.semantic === false) args.push("--no-semantic");
|
|
467
|
+
return args;
|
|
468
|
+
}
|
|
469
|
+
case "catalog":
|
|
470
|
+
return ["wiki", "catalog"];
|
|
471
|
+
case "record": {
|
|
472
|
+
if (!sourcePath) return "repo_knowledge action=record requires path.";
|
|
473
|
+
if (!params.classification) return "repo_knowledge action=record requires classification.";
|
|
474
|
+
if (params.sourceReviewed !== true) return "repo_knowledge record refused: read/classify the source first, then retry with sourceReviewed=true.";
|
|
475
|
+
if (["spec", "spec-like"].includes(params.classification) && (!params.behaviorType || !params.lifecycle)) {
|
|
476
|
+
return "repo_knowledge record for primary knowledge requires behaviorType and lifecycle.";
|
|
477
|
+
}
|
|
478
|
+
const args = ["wiki", "record", "--path", sourcePath, "--classification", params.classification];
|
|
479
|
+
if (params.behaviorType) args.push("--type", params.behaviorType);
|
|
480
|
+
if (params.lifecycle) args.push("--lifecycle", params.lifecycle);
|
|
481
|
+
if (params.confidence) args.push("--confidence", params.confidence);
|
|
482
|
+
if (nonEmpty(params.summary)) args.push("--summary", params.summary.trim());
|
|
483
|
+
for (const topic of topics) args.push("--topic", topic);
|
|
484
|
+
return args;
|
|
485
|
+
}
|
|
486
|
+
case "verify":
|
|
487
|
+
if (!sourcePath) return "repo_knowledge action=verify requires path.";
|
|
488
|
+
if (params.evidenceReviewed !== true) return "repo_knowledge verify refused: inspect the primary source and relevant code/tests first, then retry with evidenceReviewed=true.";
|
|
489
|
+
return ["wiki", "verify", "--path", sourcePath];
|
|
490
|
+
case "relate": {
|
|
491
|
+
if (!sourcePath) return "repo_knowledge action=relate requires path.";
|
|
492
|
+
if (params.evidenceReviewed !== true) return "repo_knowledge relate refused: review concrete evidence first; semantic/graph similarity alone is insufficient. Retry with evidenceReviewed=true.";
|
|
493
|
+
if (!params.relationAction || !params.relationKind || targets.length === 0) {
|
|
494
|
+
return "repo_knowledge relate requires relationAction, relationKind, and targetPaths.";
|
|
495
|
+
}
|
|
496
|
+
const flags: Record<KnowledgeRelationKind, Record<KnowledgeRelationAction, string>> = {
|
|
497
|
+
implements: { add: "--add-code", remove: "--remove-code" },
|
|
498
|
+
tests: { add: "--add-test", remove: "--remove-test" },
|
|
499
|
+
related: { add: "--add-related-spec", remove: "--remove-related-spec" },
|
|
500
|
+
supersedes: { add: "--add-supersedes", remove: "--remove-supersedes" },
|
|
501
|
+
"superseded-by": { add: "--add-superseded-by", remove: "--remove-superseded-by" },
|
|
502
|
+
};
|
|
503
|
+
const args = ["wiki", "relate", "--path", sourcePath];
|
|
504
|
+
const flag = flags[params.relationKind][params.relationAction];
|
|
505
|
+
for (const target of targets) args.push(flag, target);
|
|
506
|
+
return args;
|
|
507
|
+
}
|
|
508
|
+
case "remove":
|
|
509
|
+
if (!sourcePath) return "repo_knowledge action=remove requires path.";
|
|
510
|
+
if (params.metadataOnlyConfirmed !== true) return "repo_knowledge remove refused: confirm that only knowledge metadata should be removed and the source document must remain, then retry with metadataOnlyConfirmed=true.";
|
|
511
|
+
return ["wiki", "remove", "--path", sourcePath];
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
async function executeRepoKnowledge(
|
|
516
|
+
pi: ExtensionAPI,
|
|
517
|
+
params: RepoKnowledgeParams,
|
|
518
|
+
signal: AbortSignal | undefined,
|
|
519
|
+
ctx: ToolContext,
|
|
520
|
+
profile: RepoDiscoveryProfile,
|
|
521
|
+
) {
|
|
522
|
+
if (signal?.aborted) return textResult("repo_knowledge cancelled");
|
|
523
|
+
const idxArgs = buildRepoKnowledgeArgs(params);
|
|
524
|
+
if (typeof idxArgs === "string") return textResult(idxArgs, true, { action: params.action });
|
|
525
|
+
|
|
526
|
+
const indexedProject = ensureIndexedProject(ctx.cwd, "repo_knowledge");
|
|
527
|
+
if (indexedProject.error) return textResult(indexedProject.error, true, { projectRoot: indexedProject.projectRoot, action: params.action });
|
|
528
|
+
|
|
529
|
+
const result = await runQueuedIdx(indexedProject.projectRoot, () =>
|
|
530
|
+
pi.exec("idx", idxArgs, { cwd: indexedProject.projectRoot, signal, timeout: 180_000 }),
|
|
531
|
+
);
|
|
532
|
+
const exitCode = result.code ?? 0;
|
|
533
|
+
const combined = [result.stdout, result.stderr].filter(Boolean).join(result.stdout && result.stderr ? "\n" : "");
|
|
534
|
+
const output = combined.trim() ? combined : "No output";
|
|
535
|
+
const native = profile === "native-compact";
|
|
536
|
+
const maxLines = positiveInteger(params.maxLines, native ? 400 : 600);
|
|
537
|
+
const maxBytes = positiveInteger(params.maxBytes, native ? 12_000 : 20_000);
|
|
538
|
+
const truncated = native
|
|
539
|
+
? truncateNativeCompactOutput(output, Math.min(maxLines, params.outputMode === "full" ? 2_000 : 400), Math.min(maxBytes, params.outputMode === "full" ? 50_000 : 12_000), params.outputMode ?? "compact")
|
|
540
|
+
: truncateOutput(output, Math.min(maxLines, 2_000), Math.min(maxBytes, 50_000));
|
|
541
|
+
|
|
542
|
+
return textResult(truncated.text, exitCode !== 0, {
|
|
543
|
+
action: params.action,
|
|
544
|
+
mutating: REPO_KNOWLEDGE_MUTATING_ACTIONS.has(params.action),
|
|
545
|
+
command: ["idx", ...idxArgs],
|
|
546
|
+
cwd: indexedProject.projectRoot,
|
|
547
|
+
exitCode,
|
|
548
|
+
truncation: truncated.truncation,
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
|
|
325
552
|
const BASELINE_REPO_TOOL_PROPERTIES = {
|
|
326
553
|
maxLines: numberSchema("Returned line cap, keeps top lines (default 2000). Prefer native limits/cursors before raising.", DEFAULT_MAX_LINES),
|
|
327
554
|
maxBytes: numberSchema("Returned byte cap, keeps top bytes (default 50000). Narrow the query before raising.", DEFAULT_MAX_BYTES),
|
|
@@ -382,6 +609,62 @@ function repoToolParameters(command: IdxCommand, targetDescription: string | und
|
|
|
382
609
|
};
|
|
383
610
|
}
|
|
384
611
|
|
|
612
|
+
function repoKnowledgeParameters(profile: RepoDiscoveryProfile) {
|
|
613
|
+
const outputProperties = profile === "native-compact"
|
|
614
|
+
? NATIVE_COMPACT_REPO_TOOL_PROPERTIES
|
|
615
|
+
: {
|
|
616
|
+
maxLines: numberSchema("Returned line cap for knowledge output (default 600; max delivery 2000). Narrow the action/query first.", 600),
|
|
617
|
+
maxBytes: numberSchema("Returned byte cap for knowledge output (default 20000; max delivery 50000). Narrow before raising.", 20_000),
|
|
618
|
+
};
|
|
619
|
+
return {
|
|
620
|
+
type: "object",
|
|
621
|
+
properties: {
|
|
622
|
+
action: {
|
|
623
|
+
type: "string",
|
|
624
|
+
enum: [...REPO_KNOWLEDGE_ACTIONS],
|
|
625
|
+
description: "Knowledge action. record/verify/relate/remove mutate idx knowledge metadata; source spec files are edited with normal file tools.",
|
|
626
|
+
},
|
|
627
|
+
query: stringSchema("Behavior/contract query for context or search."),
|
|
628
|
+
path: stringSchema("Project-relative primary knowledge path for show/record/verify/relate/remove."),
|
|
629
|
+
paths: { type: "array", items: stringSchema("Project-relative task-changed path"), description: "Task-scoped changed paths for impact. Prefer this over whole-worktree fallback." },
|
|
630
|
+
classification: { type: "string", enum: ["spec", "spec-like", "meta-index", "design-only", "guide", "other"] },
|
|
631
|
+
behaviorType: { type: "string", enum: ["as-is", "change", "mixed", "unknown"] },
|
|
632
|
+
lifecycle: { type: "string", enum: ["active", "proposed", "historical", "superseded", "unknown"] },
|
|
633
|
+
confidence: { type: "string", enum: ["high", "medium", "low", "unknown"] },
|
|
634
|
+
summary: stringSchema("Compact retrieval summary based on the reviewed primary source; never invent behavior."),
|
|
635
|
+
topics: { type: "array", items: stringSchema("Retrieval topic") },
|
|
636
|
+
includeSecondary: { type: "boolean", description: "Include design-only secondary knowledge for context/search." },
|
|
637
|
+
pathPrefix: stringSchema("Optional project-relative scope for context/search."),
|
|
638
|
+
limit: boundedIntegerSchema("Result/candidate/semantic limit depending on action.", 5, 200),
|
|
639
|
+
budget: boundedIntegerSchema("Context token budget; context only.", 1400, 8000),
|
|
640
|
+
maxSpecs: boundedIntegerSchema("Maximum primary specs in context.", 4, 20),
|
|
641
|
+
maxCode: boundedIntegerSchema("Maximum implementation ranges/files in context.", 6, 30),
|
|
642
|
+
maxTests: boundedIntegerSchema("Maximum test hints in context.", 4, 20),
|
|
643
|
+
includeAll: { type: "boolean", description: "discover: include unchanged already-classified documents." },
|
|
644
|
+
allUnclassified: { type: "boolean", description: "discover: include all unclassified document-like files regardless heuristic score." },
|
|
645
|
+
base: stringSchema("Git base for impact when task-scoped paths are omitted; default HEAD."),
|
|
646
|
+
semantic: { type: "boolean", description: "impact semantic candidate retrieval; default true." },
|
|
647
|
+
relationAction: { type: "string", enum: ["add", "remove"] },
|
|
648
|
+
relationKind: { type: "string", enum: ["implements", "tests", "related", "supersedes", "superseded-by"] },
|
|
649
|
+
targetPaths: { type: "array", items: stringSchema("Reviewed relation target path") },
|
|
650
|
+
sourceReviewed: { type: "boolean", description: "Required true for record only after reading/classifying the source document." },
|
|
651
|
+
evidenceReviewed: { type: "boolean", description: "Required true for verify/relate only after reviewing concrete primary source + relevant code/tests/evidence." },
|
|
652
|
+
metadataOnlyConfirmed: { type: "boolean", description: "Required true for remove; confirms only idx metadata is removed and the source file stays untouched." },
|
|
653
|
+
...outputProperties,
|
|
654
|
+
...(profile === "native-compact" ? {
|
|
655
|
+
outputMode: {
|
|
656
|
+
type: "string",
|
|
657
|
+
enum: ["compact", "full"],
|
|
658
|
+
default: "compact",
|
|
659
|
+
description: "Knowledge output delivery mode. Keep compact unless this same result is actually truncated and broader output is necessary.",
|
|
660
|
+
},
|
|
661
|
+
} : {}),
|
|
662
|
+
},
|
|
663
|
+
required: ["action"],
|
|
664
|
+
additionalProperties: false,
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
|
|
385
668
|
function registerRepoCommandTool(
|
|
386
669
|
pi: ExtensionAPI,
|
|
387
670
|
options: {
|
|
@@ -409,6 +692,22 @@ function registerRepoCommandTool(
|
|
|
409
692
|
});
|
|
410
693
|
}
|
|
411
694
|
|
|
695
|
+
function registerRepoKnowledgeTool(pi: ExtensionAPI, profile: RepoDiscoveryProfile) {
|
|
696
|
+
pi.registerTool({
|
|
697
|
+
...REPO_KNOWLEDGE_TOOL_DESCRIPTION,
|
|
698
|
+
parameters: repoKnowledgeParameters(profile),
|
|
699
|
+
async execute(
|
|
700
|
+
_toolCallId: string,
|
|
701
|
+
params: RepoKnowledgeParams,
|
|
702
|
+
signal: AbortSignal | undefined,
|
|
703
|
+
_onUpdate: unknown,
|
|
704
|
+
ctx: ToolContext,
|
|
705
|
+
) {
|
|
706
|
+
return executeRepoKnowledge(pi, params, signal, ctx, profile);
|
|
707
|
+
},
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
|
|
412
711
|
export type RepoDiscoveryExtensionOptions = {
|
|
413
712
|
profile?: RepoDiscoveryProfile;
|
|
414
713
|
cwd?: string;
|
|
@@ -490,8 +789,9 @@ export default function repoDiscoveryExtension(pi: ExtensionAPI, options: RepoDi
|
|
|
490
789
|
},
|
|
491
790
|
});
|
|
492
791
|
|
|
493
|
-
if (!
|
|
792
|
+
if (!hasAvailableIndexedProjectRoot(registrationCwd)) return;
|
|
494
793
|
|
|
495
794
|
for (const tool of REPO_DISCOVERY_TOOLS) registerRepoCommandTool(pi, tool, profile);
|
|
795
|
+
registerRepoKnowledgeTool(pi, profile);
|
|
496
796
|
|
|
497
797
|
}
|