indusagi-coding-agent 0.1.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/CHANGELOG.md +2249 -0
- package/README.md +546 -0
- package/dist/cli/args.js +282 -0
- package/dist/cli/config-selector.js +30 -0
- package/dist/cli/file-processor.js +78 -0
- package/dist/cli/list-models.js +91 -0
- package/dist/cli/session-picker.js +31 -0
- package/dist/cli.js +10 -0
- package/dist/config.js +158 -0
- package/dist/core/agent-session.js +2097 -0
- package/dist/core/auth-storage.js +278 -0
- package/dist/core/bash-executor.js +211 -0
- package/dist/core/compaction/branch-summarization.js +241 -0
- package/dist/core/compaction/compaction.js +606 -0
- package/dist/core/compaction/index.js +6 -0
- package/dist/core/compaction/utils.js +137 -0
- package/dist/core/diagnostics.js +1 -0
- package/dist/core/event-bus.js +24 -0
- package/dist/core/exec.js +70 -0
- package/dist/core/export-html/ansi-to-html.js +248 -0
- package/dist/core/export-html/index.js +221 -0
- package/dist/core/export-html/template.css +905 -0
- package/dist/core/export-html/template.html +54 -0
- package/dist/core/export-html/template.js +1549 -0
- package/dist/core/export-html/tool-renderer.js +56 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +6 -0
- package/dist/core/extensions/index.js +8 -0
- package/dist/core/extensions/loader.js +395 -0
- package/dist/core/extensions/runner.js +499 -0
- package/dist/core/extensions/types.js +31 -0
- package/dist/core/extensions/wrapper.js +101 -0
- package/dist/core/footer-data-provider.js +133 -0
- package/dist/core/index.js +8 -0
- package/dist/core/keybindings.js +140 -0
- package/dist/core/messages.js +122 -0
- package/dist/core/model-registry.js +454 -0
- package/dist/core/model-resolver.js +309 -0
- package/dist/core/package-manager.js +1142 -0
- package/dist/core/prompt-templates.js +250 -0
- package/dist/core/resource-loader.js +569 -0
- package/dist/core/sdk.js +225 -0
- package/dist/core/session-manager.js +1078 -0
- package/dist/core/settings-manager.js +430 -0
- package/dist/core/skills.js +339 -0
- package/dist/core/system-prompt.js +136 -0
- package/dist/core/timings.js +24 -0
- package/dist/core/tools/bash.js +226 -0
- package/dist/core/tools/edit-diff.js +242 -0
- package/dist/core/tools/edit.js +145 -0
- package/dist/core/tools/find.js +205 -0
- package/dist/core/tools/grep.js +238 -0
- package/dist/core/tools/index.js +60 -0
- package/dist/core/tools/ls.js +117 -0
- package/dist/core/tools/path-utils.js +52 -0
- package/dist/core/tools/read.js +165 -0
- package/dist/core/tools/truncate.js +204 -0
- package/dist/core/tools/write.js +77 -0
- package/dist/index.js +41 -0
- package/dist/main.js +565 -0
- package/dist/migrations.js +260 -0
- package/dist/modes/index.js +7 -0
- package/dist/modes/interactive/components/armin.js +328 -0
- package/dist/modes/interactive/components/assistant-message.js +86 -0
- package/dist/modes/interactive/components/bash-execution.js +155 -0
- package/dist/modes/interactive/components/bordered-loader.js +47 -0
- package/dist/modes/interactive/components/branch-summary-message.js +41 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +42 -0
- package/dist/modes/interactive/components/config-selector.js +458 -0
- package/dist/modes/interactive/components/countdown-timer.js +27 -0
- package/dist/modes/interactive/components/custom-editor.js +61 -0
- package/dist/modes/interactive/components/custom-message.js +80 -0
- package/dist/modes/interactive/components/diff.js +132 -0
- package/dist/modes/interactive/components/dynamic-border.js +19 -0
- package/dist/modes/interactive/components/extension-editor.js +96 -0
- package/dist/modes/interactive/components/extension-input.js +54 -0
- package/dist/modes/interactive/components/extension-selector.js +70 -0
- package/dist/modes/interactive/components/footer.js +213 -0
- package/dist/modes/interactive/components/index.js +31 -0
- package/dist/modes/interactive/components/keybinding-hints.js +60 -0
- package/dist/modes/interactive/components/login-dialog.js +138 -0
- package/dist/modes/interactive/components/model-selector.js +253 -0
- package/dist/modes/interactive/components/oauth-selector.js +91 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +262 -0
- package/dist/modes/interactive/components/session-selector-search.js +145 -0
- package/dist/modes/interactive/components/session-selector.js +698 -0
- package/dist/modes/interactive/components/settings-selector.js +250 -0
- package/dist/modes/interactive/components/show-images-selector.js +33 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +44 -0
- package/dist/modes/interactive/components/theme-selector.js +43 -0
- package/dist/modes/interactive/components/thinking-selector.js +45 -0
- package/dist/modes/interactive/components/tool-execution.js +608 -0
- package/dist/modes/interactive/components/tree-selector.js +892 -0
- package/dist/modes/interactive/components/user-message-selector.js +109 -0
- package/dist/modes/interactive/components/user-message.js +15 -0
- package/dist/modes/interactive/components/visual-truncate.js +32 -0
- package/dist/modes/interactive/interactive-mode.js +3576 -0
- package/dist/modes/interactive/theme/dark.json +85 -0
- package/dist/modes/interactive/theme/light.json +84 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.js +938 -0
- package/dist/modes/print-mode.js +96 -0
- package/dist/modes/rpc/rpc-client.js +390 -0
- package/dist/modes/rpc/rpc-mode.js +448 -0
- package/dist/modes/rpc/rpc-types.js +7 -0
- package/dist/utils/changelog.js +86 -0
- package/dist/utils/clipboard-image.js +116 -0
- package/dist/utils/clipboard.js +58 -0
- package/dist/utils/frontmatter.js +25 -0
- package/dist/utils/git.js +5 -0
- package/dist/utils/image-convert.js +34 -0
- package/dist/utils/image-resize.js +180 -0
- package/dist/utils/mime.js +25 -0
- package/dist/utils/photon.js +120 -0
- package/dist/utils/shell.js +164 -0
- package/dist/utils/sleep.js +16 -0
- package/dist/utils/tools-manager.js +186 -0
- package/docs/compaction.md +390 -0
- package/docs/custom-provider.md +538 -0
- package/docs/development.md +69 -0
- package/docs/extensions.md +1733 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/json.md +79 -0
- package/docs/keybindings.md +162 -0
- package/docs/models.md +193 -0
- package/docs/packages.md +163 -0
- package/docs/prompt-templates.md +67 -0
- package/docs/providers.md +147 -0
- package/docs/rpc.md +1048 -0
- package/docs/sdk.md +957 -0
- package/docs/session.md +412 -0
- package/docs/settings.md +216 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +226 -0
- package/docs/terminal-setup.md +65 -0
- package/docs/themes.md +295 -0
- package/docs/tree.md +219 -0
- package/docs/tui.md +887 -0
- package/docs/windows.md +17 -0
- package/examples/README.md +25 -0
- package/examples/extensions/README.md +192 -0
- package/examples/extensions/antigravity-image-gen.ts +414 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +115 -0
- package/examples/extensions/custom-footer.ts +65 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +605 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +350 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +83 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +133 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +105 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/handoff.ts +151 -0
- package/examples/extensions/hello.ts +25 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +60 -0
- package/examples/extensions/modal-editor.ts +86 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +25 -0
- package/examples/extensions/overlay-qa-tests.ts +882 -0
- package/examples/extensions/overlay-test.ts +151 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +341 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +399 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/qna.ts +120 -0
- package/examples/extensions/question.ts +265 -0
- package/examples/extensions/questionnaire.ts +428 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/sandbox/index.ts +318 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +344 -0
- package/examples/extensions/space-invaders.ts +561 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/status-line.ts +40 -0
- package/examples/extensions/subagent/README.md +172 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +127 -0
- package/examples/extensions/subagent/index.ts +964 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +196 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/todo.ts +300 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +147 -0
- package/examples/extensions/trigger-compact.ts +40 -0
- package/examples/extensions/truncated-tool.ts +193 -0
- package/examples/extensions/widget-placement.ts +17 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +50 -0
- package/examples/sdk/03-custom-prompt.ts +55 -0
- package/examples/sdk/04-skills.ts +46 -0
- package/examples/sdk/05-tools.ts +56 -0
- package/examples/sdk/06-extensions.ts +88 -0
- package/examples/sdk/07-context-files.ts +40 -0
- package/examples/sdk/08-prompt-templates.ts +47 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
- package/examples/sdk/10-settings.ts +38 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +82 -0
- package/examples/sdk/13-codex-oauth.ts +37 -0
- package/examples/sdk/README.md +144 -0
- package/package.json +85 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "fs";
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { basename, isAbsolute, join, resolve, sep } from "path";
|
|
4
|
+
import { CONFIG_DIR_NAME, getPromptsDir } from "../config.js";
|
|
5
|
+
import { parseFrontmatter } from "../utils/frontmatter.js";
|
|
6
|
+
/**
|
|
7
|
+
* Parse command arguments respecting quoted strings (bash-style)
|
|
8
|
+
* Returns array of arguments
|
|
9
|
+
*/
|
|
10
|
+
export function parseCommandArgs(argsString) {
|
|
11
|
+
const args = [];
|
|
12
|
+
let current = "";
|
|
13
|
+
let inQuote = null;
|
|
14
|
+
for (let i = 0; i < argsString.length; i++) {
|
|
15
|
+
const char = argsString[i];
|
|
16
|
+
if (inQuote) {
|
|
17
|
+
if (char === inQuote) {
|
|
18
|
+
inQuote = null;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
current += char;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (char === '"' || char === "'") {
|
|
25
|
+
inQuote = char;
|
|
26
|
+
}
|
|
27
|
+
else if (char === " " || char === "\t") {
|
|
28
|
+
if (current) {
|
|
29
|
+
args.push(current);
|
|
30
|
+
current = "";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
current += char;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (current) {
|
|
38
|
+
args.push(current);
|
|
39
|
+
}
|
|
40
|
+
return args;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Substitute argument placeholders in template content
|
|
44
|
+
* Supports:
|
|
45
|
+
* - $1, $2, ... for positional args
|
|
46
|
+
* - $@ and $ARGUMENTS for all args
|
|
47
|
+
* - ${@:N} for args from Nth onwards (bash-style slicing)
|
|
48
|
+
* - ${@:N:L} for L args starting from Nth
|
|
49
|
+
*
|
|
50
|
+
* Note: Replacement happens on the template string only. Argument values
|
|
51
|
+
* containing patterns like $1, $@, or $ARGUMENTS are NOT recursively substituted.
|
|
52
|
+
*/
|
|
53
|
+
export function substituteArgs(content, args) {
|
|
54
|
+
let result = content;
|
|
55
|
+
// Replace $1, $2, etc. with positional args FIRST (before wildcards)
|
|
56
|
+
// This prevents wildcard replacement values containing $<digit> patterns from being re-substituted
|
|
57
|
+
result = result.replace(/\$(\d+)/g, (_, num) => {
|
|
58
|
+
const index = parseInt(num, 10) - 1;
|
|
59
|
+
return args[index] ?? "";
|
|
60
|
+
});
|
|
61
|
+
// Replace ${@:start} or ${@:start:length} with sliced args (bash-style)
|
|
62
|
+
// Process BEFORE simple $@ to avoid conflicts
|
|
63
|
+
result = result.replace(/\$\{@:(\d+)(?::(\d+))?\}/g, (_, startStr, lengthStr) => {
|
|
64
|
+
let start = parseInt(startStr, 10) - 1; // Convert to 0-indexed (user provides 1-indexed)
|
|
65
|
+
// Treat 0 as 1 (bash convention: args start at 1)
|
|
66
|
+
if (start < 0)
|
|
67
|
+
start = 0;
|
|
68
|
+
if (lengthStr) {
|
|
69
|
+
const length = parseInt(lengthStr, 10);
|
|
70
|
+
return args.slice(start, start + length).join(" ");
|
|
71
|
+
}
|
|
72
|
+
return args.slice(start).join(" ");
|
|
73
|
+
});
|
|
74
|
+
// Pre-compute all args joined (optimization)
|
|
75
|
+
const allArgs = args.join(" ");
|
|
76
|
+
// Replace $ARGUMENTS with all args joined (new syntax, aligns with Claude, Codex, OpenCode)
|
|
77
|
+
result = result.replace(/\$ARGUMENTS/g, allArgs);
|
|
78
|
+
// Replace $@ with all args joined (existing syntax)
|
|
79
|
+
result = result.replace(/\$@/g, allArgs);
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
function loadTemplateFromFile(filePath, source, sourceLabel) {
|
|
83
|
+
try {
|
|
84
|
+
const rawContent = readFileSync(filePath, "utf-8");
|
|
85
|
+
const { frontmatter, body } = parseFrontmatter(rawContent);
|
|
86
|
+
const name = basename(filePath).replace(/\.md$/, "");
|
|
87
|
+
// Get description from frontmatter or first non-empty line
|
|
88
|
+
let description = frontmatter.description || "";
|
|
89
|
+
if (!description) {
|
|
90
|
+
const firstLine = body.split("\n").find((line) => line.trim());
|
|
91
|
+
if (firstLine) {
|
|
92
|
+
// Truncate if too long
|
|
93
|
+
description = firstLine.slice(0, 60);
|
|
94
|
+
if (firstLine.length > 60)
|
|
95
|
+
description += "...";
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Append source to description
|
|
99
|
+
description = description ? `${description} ${sourceLabel}` : sourceLabel;
|
|
100
|
+
return {
|
|
101
|
+
name,
|
|
102
|
+
description,
|
|
103
|
+
content: body,
|
|
104
|
+
source,
|
|
105
|
+
filePath,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Scan a directory for .md files (non-recursive) and load them as prompt templates.
|
|
114
|
+
*/
|
|
115
|
+
function loadTemplatesFromDir(dir, source, sourceLabel) {
|
|
116
|
+
const templates = [];
|
|
117
|
+
if (!existsSync(dir)) {
|
|
118
|
+
return templates;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
122
|
+
for (const entry of entries) {
|
|
123
|
+
const fullPath = join(dir, entry.name);
|
|
124
|
+
// For symlinks, check if they point to a file
|
|
125
|
+
let isFile = entry.isFile();
|
|
126
|
+
if (entry.isSymbolicLink()) {
|
|
127
|
+
try {
|
|
128
|
+
const stats = statSync(fullPath);
|
|
129
|
+
isFile = stats.isFile();
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Broken symlink, skip it
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (isFile && entry.name.endsWith(".md")) {
|
|
137
|
+
const template = loadTemplateFromFile(fullPath, source, sourceLabel);
|
|
138
|
+
if (template) {
|
|
139
|
+
templates.push(template);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return templates;
|
|
146
|
+
}
|
|
147
|
+
return templates;
|
|
148
|
+
}
|
|
149
|
+
function normalizePath(input) {
|
|
150
|
+
const trimmed = input.trim();
|
|
151
|
+
if (trimmed === "~")
|
|
152
|
+
return homedir();
|
|
153
|
+
if (trimmed.startsWith("~/"))
|
|
154
|
+
return join(homedir(), trimmed.slice(2));
|
|
155
|
+
if (trimmed.startsWith("~"))
|
|
156
|
+
return join(homedir(), trimmed.slice(1));
|
|
157
|
+
return trimmed;
|
|
158
|
+
}
|
|
159
|
+
function resolvePromptPath(p, cwd) {
|
|
160
|
+
const normalized = normalizePath(p);
|
|
161
|
+
return isAbsolute(normalized) ? normalized : resolve(cwd, normalized);
|
|
162
|
+
}
|
|
163
|
+
function buildPathSourceLabel(p) {
|
|
164
|
+
const base = basename(p).replace(/\.md$/, "") || "path";
|
|
165
|
+
return `(path:${base})`;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Load all prompt templates from:
|
|
169
|
+
* 1. Global: agentDir/prompts/
|
|
170
|
+
* 2. Project: cwd/{CONFIG_DIR_NAME}/prompts/
|
|
171
|
+
* 3. Explicit prompt paths
|
|
172
|
+
*/
|
|
173
|
+
export function loadPromptTemplates(options = {}) {
|
|
174
|
+
const resolvedCwd = options.cwd ?? process.cwd();
|
|
175
|
+
const resolvedAgentDir = options.agentDir ?? getPromptsDir();
|
|
176
|
+
const promptPaths = options.promptPaths ?? [];
|
|
177
|
+
const includeDefaults = options.includeDefaults ?? true;
|
|
178
|
+
const templates = [];
|
|
179
|
+
if (includeDefaults) {
|
|
180
|
+
// 1. Load global templates from agentDir/prompts/
|
|
181
|
+
// Note: if agentDir is provided, it should be the agent dir, not the prompts dir
|
|
182
|
+
const globalPromptsDir = options.agentDir ? join(options.agentDir, "prompts") : resolvedAgentDir;
|
|
183
|
+
templates.push(...loadTemplatesFromDir(globalPromptsDir, "user", "(user)"));
|
|
184
|
+
// 2. Load project templates from cwd/{CONFIG_DIR_NAME}/prompts/
|
|
185
|
+
const projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, "prompts");
|
|
186
|
+
templates.push(...loadTemplatesFromDir(projectPromptsDir, "project", "(project)"));
|
|
187
|
+
}
|
|
188
|
+
const userPromptsDir = options.agentDir ? join(options.agentDir, "prompts") : resolvedAgentDir;
|
|
189
|
+
const projectPromptsDir = resolve(resolvedCwd, CONFIG_DIR_NAME, "prompts");
|
|
190
|
+
const isUnderPath = (target, root) => {
|
|
191
|
+
const normalizedRoot = resolve(root);
|
|
192
|
+
if (target === normalizedRoot) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
const prefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;
|
|
196
|
+
return target.startsWith(prefix);
|
|
197
|
+
};
|
|
198
|
+
const getSourceInfo = (resolvedPath) => {
|
|
199
|
+
if (!includeDefaults) {
|
|
200
|
+
if (isUnderPath(resolvedPath, userPromptsDir)) {
|
|
201
|
+
return { source: "user", label: "(user)" };
|
|
202
|
+
}
|
|
203
|
+
if (isUnderPath(resolvedPath, projectPromptsDir)) {
|
|
204
|
+
return { source: "project", label: "(project)" };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return { source: "path", label: buildPathSourceLabel(resolvedPath) };
|
|
208
|
+
};
|
|
209
|
+
// 3. Load explicit prompt paths
|
|
210
|
+
for (const rawPath of promptPaths) {
|
|
211
|
+
const resolvedPath = resolvePromptPath(rawPath, resolvedCwd);
|
|
212
|
+
if (!existsSync(resolvedPath)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
try {
|
|
216
|
+
const stats = statSync(resolvedPath);
|
|
217
|
+
const { source, label } = getSourceInfo(resolvedPath);
|
|
218
|
+
if (stats.isDirectory()) {
|
|
219
|
+
templates.push(...loadTemplatesFromDir(resolvedPath, source, label));
|
|
220
|
+
}
|
|
221
|
+
else if (stats.isFile() && resolvedPath.endsWith(".md")) {
|
|
222
|
+
const template = loadTemplateFromFile(resolvedPath, source, label);
|
|
223
|
+
if (template) {
|
|
224
|
+
templates.push(template);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Ignore read failures
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return templates;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Expand a prompt template if it matches a template name.
|
|
236
|
+
* Returns the expanded content or the original text if not a template.
|
|
237
|
+
*/
|
|
238
|
+
export function expandPromptTemplate(text, templates) {
|
|
239
|
+
if (!text.startsWith("/"))
|
|
240
|
+
return text;
|
|
241
|
+
const spaceIndex = text.indexOf(" ");
|
|
242
|
+
const templateName = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
|
|
243
|
+
const argsString = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1);
|
|
244
|
+
const template = templates.find((t) => t.name === templateName);
|
|
245
|
+
if (template) {
|
|
246
|
+
const args = parseCommandArgs(argsString);
|
|
247
|
+
return substituteArgs(template.content, args);
|
|
248
|
+
}
|
|
249
|
+
return text;
|
|
250
|
+
}
|