@apholdings/jensen-code 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +6 -6
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +6 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +32 -25
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +25 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +1 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +4 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +25 -11
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +5 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +0 -2
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -146
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/header.d.ts +9 -3
- package/dist/modes/interactive/components/header.d.ts.map +1 -1
- package/dist/modes/interactive/components/header.js +125 -196
- package/dist/modes/interactive/components/header.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +1 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +23 -4
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +657 -243
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +2 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +8 -4
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +2 -2
- package/dist/utils/tools-manager.js.map +1 -1
- package/examples/extensions/osgrep.ts +643 -0
- package/examples/extensions/subagent/agents.ts +150 -38
- package/examples/extensions/subagent/index.ts +634 -514
- package/package.json +4 -3
- package/examples/README.md +0 -25
- package/examples/extensions/README.md +0 -206
- package/examples/extensions/antigravity-image-gen.ts +0 -416
- package/examples/extensions/auto-commit-on-exit.ts +0 -50
- package/examples/extensions/bash-spawn-hook.ts +0 -31
- package/examples/extensions/bookmark.ts +0 -51
- package/examples/extensions/built-in-tool-renderer.ts +0 -247
- package/examples/extensions/claude-rules.ts +0 -87
- package/examples/extensions/commands.ts +0 -73
- package/examples/extensions/confirm-destructive.ts +0 -60
- package/examples/extensions/custom-compaction.ts +0 -115
- package/examples/extensions/custom-footer.ts +0 -65
- package/examples/extensions/custom-header.ts +0 -74
- package/examples/extensions/custom-provider-anthropic/index.ts +0 -605
- package/examples/extensions/custom-provider-anthropic/package-lock.json +0 -24
- package/examples/extensions/custom-provider-anthropic/package.json +0 -19
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +0 -350
- package/examples/extensions/custom-provider-gitlab-duo/package.json +0 -16
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +0 -82
- package/examples/extensions/custom-provider-qwen-cli/index.ts +0 -346
- package/examples/extensions/custom-provider-qwen-cli/package.json +0 -16
- package/examples/extensions/dirty-repo-guard.ts +0 -57
- package/examples/extensions/doom-overlay/README.md +0 -46
- package/examples/extensions/doom-overlay/doom/build/doom.js +0 -21
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +0 -152
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +0 -72
- package/examples/extensions/doom-overlay/doom-component.ts +0 -132
- package/examples/extensions/doom-overlay/doom-engine.ts +0 -173
- package/examples/extensions/doom-overlay/doom-keys.ts +0 -104
- package/examples/extensions/doom-overlay/index.ts +0 -75
- package/examples/extensions/doom-overlay/wad-finder.ts +0 -51
- package/examples/extensions/dynamic-resources/SKILL.md +0 -8
- package/examples/extensions/dynamic-resources/dynamic.json +0 -79
- package/examples/extensions/dynamic-resources/dynamic.md +0 -5
- package/examples/extensions/dynamic-resources/index.ts +0 -16
- package/examples/extensions/dynamic-tools.ts +0 -75
- package/examples/extensions/event-bus.ts +0 -44
- package/examples/extensions/file-trigger.ts +0 -42
- package/examples/extensions/git-checkpoint.ts +0 -54
- package/examples/extensions/handoff.ts +0 -151
- package/examples/extensions/hello.ts +0 -26
- package/examples/extensions/inline-bash.ts +0 -95
- package/examples/extensions/input-transform.ts +0 -44
- package/examples/extensions/interactive-shell.ts +0 -197
- package/examples/extensions/mac-system-theme.ts +0 -48
- package/examples/extensions/message-renderer.ts +0 -60
- package/examples/extensions/minimal-mode.ts +0 -427
- package/examples/extensions/modal-editor.ts +0 -86
- package/examples/extensions/model-status.ts +0 -32
- package/examples/extensions/notify.ts +0 -56
- package/examples/extensions/overlay-qa-tests.ts +0 -1349
- package/examples/extensions/overlay-test.ts +0 -151
- package/examples/extensions/permission-gate.ts +0 -35
- package/examples/extensions/pirate.ts +0 -48
- package/examples/extensions/plan-mode/README.md +0 -65
- package/examples/extensions/plan-mode/index.ts +0 -341
- package/examples/extensions/plan-mode/utils.ts +0 -168
- package/examples/extensions/preset.ts +0 -399
- package/examples/extensions/protected-paths.ts +0 -31
- package/examples/extensions/provider-payload.ts +0 -15
- package/examples/extensions/qna.ts +0 -120
- package/examples/extensions/question.ts +0 -265
- package/examples/extensions/questionnaire.ts +0 -428
- package/examples/extensions/rainbow-editor.ts +0 -89
- package/examples/extensions/reload-runtime.ts +0 -38
- package/examples/extensions/rpc-demo.ts +0 -125
- package/examples/extensions/sandbox/index.ts +0 -319
- package/examples/extensions/sandbox/package-lock.json +0 -92
- package/examples/extensions/sandbox/package.json +0 -19
- package/examples/extensions/send-user-message.ts +0 -98
- package/examples/extensions/session-name.ts +0 -28
- package/examples/extensions/shutdown-command.ts +0 -64
- package/examples/extensions/snake.ts +0 -344
- package/examples/extensions/space-invaders.ts +0 -561
- package/examples/extensions/ssh.ts +0 -221
- package/examples/extensions/status-line.ts +0 -41
- package/examples/extensions/subagent/README.md +0 -172
- package/examples/extensions/subagent/agents/planner.md +0 -37
- package/examples/extensions/subagent/agents/reviewer.md +0 -35
- package/examples/extensions/subagent/agents/scout.md +0 -50
- package/examples/extensions/subagent/agents/worker.md +0 -24
- package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
- package/examples/extensions/subagent/prompts/implement.md +0 -10
- package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
- package/examples/extensions/summarize.ts +0 -196
- package/examples/extensions/system-prompt-header.ts +0 -18
- package/examples/extensions/timed-confirm.ts +0 -71
- package/examples/extensions/titlebar-spinner.ts +0 -59
- package/examples/extensions/todo.ts +0 -300
- package/examples/extensions/tool-override.ts +0 -144
- package/examples/extensions/tools.ts +0 -147
- package/examples/extensions/trigger-compact.ts +0 -41
- package/examples/extensions/truncated-tool.ts +0 -193
- package/examples/extensions/widget-placement.ts +0 -18
- package/examples/extensions/with-deps/index.ts +0 -33
- package/examples/extensions/with-deps/package-lock.json +0 -31
- package/examples/extensions/with-deps/package.json +0 -22
- package/examples/rpc-extension-ui.ts +0 -632
- package/examples/sdk/01-minimal.ts +0 -23
- package/examples/sdk/02-custom-model.ts +0 -50
- package/examples/sdk/03-custom-prompt.ts +0 -56
- package/examples/sdk/04-skills.ts +0 -47
- package/examples/sdk/05-tools.ts +0 -57
- package/examples/sdk/06-extensions.ts +0 -89
- package/examples/sdk/07-context-files.ts +0 -41
- package/examples/sdk/08-prompt-templates.ts +0 -48
- package/examples/sdk/09-api-keys-and-oauth.ts +0 -49
- package/examples/sdk/10-settings.ts +0 -52
- package/examples/sdk/11-sessions.ts +0 -49
- package/examples/sdk/12-full-control.ts +0 -83
- package/examples/sdk/README.md +0 -145
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
import * as fs from "node:fs";
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import { getAgentDir, parseFrontmatter } from "@apholdings/jensen-code";
|
|
7
|
+
import { CONFIG_DIR_NAME, getAgentDir, parseFrontmatter } from "@apholdings/jensen-code";
|
|
8
8
|
|
|
9
9
|
export type AgentScope = "user" | "project" | "both";
|
|
10
|
+
export type AgentSource = "user" | "project";
|
|
10
11
|
|
|
11
12
|
export interface AgentConfig {
|
|
12
13
|
name: string;
|
|
@@ -14,105 +15,209 @@ export interface AgentConfig {
|
|
|
14
15
|
tools?: string[];
|
|
15
16
|
model?: string;
|
|
16
17
|
systemPrompt: string;
|
|
17
|
-
source:
|
|
18
|
+
source: AgentSource;
|
|
18
19
|
filePath: string;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
export type AgentDiscoveryErrorCode = "read_error" | "parse_error" | "validation_error";
|
|
23
|
+
|
|
24
|
+
export interface AgentDiscoveryError {
|
|
25
|
+
code: AgentDiscoveryErrorCode;
|
|
26
|
+
path: string;
|
|
27
|
+
source: AgentSource;
|
|
28
|
+
reason: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
21
31
|
export interface AgentDiscoveryResult {
|
|
22
32
|
agents: AgentConfig[];
|
|
23
33
|
projectAgentsDir: string | null;
|
|
34
|
+
errors: AgentDiscoveryError[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function normalizeFsPath(filePath: string): string {
|
|
38
|
+
return path.normalize(path.resolve(filePath));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeAgentName(value: unknown): string | null {
|
|
42
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function normalizeAgentDescription(value: unknown): string | null {
|
|
46
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
24
47
|
}
|
|
25
48
|
|
|
26
|
-
function
|
|
49
|
+
function normalizeAgentTools(value: unknown): string[] | undefined {
|
|
50
|
+
if (typeof value === "string") {
|
|
51
|
+
const tools = value
|
|
52
|
+
.split(",")
|
|
53
|
+
.map((tool) => tool.trim())
|
|
54
|
+
.filter((tool) => tool.length > 0);
|
|
55
|
+
return tools.length > 0 ? tools : undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
const tools = value
|
|
60
|
+
.filter((tool): tool is string => typeof tool === "string")
|
|
61
|
+
.map((tool) => tool.trim())
|
|
62
|
+
.filter((tool) => tool.length > 0);
|
|
63
|
+
return tools.length > 0 ? tools : undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function normalizeAgentModel(value: unknown): string | undefined {
|
|
70
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function formatYamlError(error: unknown): string {
|
|
74
|
+
if (error instanceof Error && error.message.trim().length > 0) {
|
|
75
|
+
return error.message.trim();
|
|
76
|
+
}
|
|
77
|
+
return String(error);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function loadAgentsFromDir(dir: string, source: AgentSource): { agents: AgentConfig[]; errors: AgentDiscoveryError[] } {
|
|
27
81
|
const agents: AgentConfig[] = [];
|
|
82
|
+
const errors: AgentDiscoveryError[] = [];
|
|
83
|
+
const normalizedDir = normalizeFsPath(dir);
|
|
28
84
|
|
|
29
|
-
if (!fs.existsSync(
|
|
30
|
-
return agents;
|
|
85
|
+
if (!fs.existsSync(normalizedDir)) {
|
|
86
|
+
return { agents, errors };
|
|
31
87
|
}
|
|
32
88
|
|
|
33
89
|
let entries: fs.Dirent[];
|
|
34
90
|
try {
|
|
35
|
-
entries = fs.readdirSync(
|
|
36
|
-
} catch {
|
|
37
|
-
|
|
91
|
+
entries = fs.readdirSync(normalizedDir, { withFileTypes: true });
|
|
92
|
+
} catch (error) {
|
|
93
|
+
errors.push({
|
|
94
|
+
code: "read_error",
|
|
95
|
+
path: normalizedDir,
|
|
96
|
+
source,
|
|
97
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
98
|
+
});
|
|
99
|
+
return { agents, errors };
|
|
38
100
|
}
|
|
39
101
|
|
|
40
102
|
for (const entry of entries) {
|
|
41
103
|
if (!entry.name.endsWith(".md")) continue;
|
|
42
104
|
if (!entry.isFile() && !entry.isSymbolicLink()) continue;
|
|
43
105
|
|
|
44
|
-
const filePath = path.join(
|
|
106
|
+
const filePath = normalizeFsPath(path.join(normalizedDir, entry.name));
|
|
45
107
|
let content: string;
|
|
46
108
|
try {
|
|
47
109
|
content = fs.readFileSync(filePath, "utf-8");
|
|
48
|
-
} catch {
|
|
110
|
+
} catch (error) {
|
|
111
|
+
errors.push({
|
|
112
|
+
code: "read_error",
|
|
113
|
+
path: filePath,
|
|
114
|
+
source,
|
|
115
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
116
|
+
});
|
|
49
117
|
continue;
|
|
50
118
|
}
|
|
51
119
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
120
|
+
let frontmatter: Record<string, unknown>;
|
|
121
|
+
let body: string;
|
|
122
|
+
try {
|
|
123
|
+
const parsed = parseFrontmatter<Record<string, unknown>>(content);
|
|
124
|
+
frontmatter = parsed.frontmatter;
|
|
125
|
+
body = parsed.body;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
errors.push({
|
|
128
|
+
code: "parse_error",
|
|
129
|
+
path: filePath,
|
|
130
|
+
source,
|
|
131
|
+
reason: formatYamlError(error),
|
|
132
|
+
});
|
|
55
133
|
continue;
|
|
56
134
|
}
|
|
57
135
|
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
.filter(
|
|
136
|
+
const name = normalizeAgentName(frontmatter.name);
|
|
137
|
+
const description = normalizeAgentDescription(frontmatter.description);
|
|
138
|
+
if (!name || !description) {
|
|
139
|
+
const missingFields = [!name ? "name" : null, !description ? "description" : null].filter(
|
|
140
|
+
(field): field is string => field !== null,
|
|
141
|
+
);
|
|
142
|
+
errors.push({
|
|
143
|
+
code: "validation_error",
|
|
144
|
+
path: filePath,
|
|
145
|
+
source,
|
|
146
|
+
reason: `Missing required frontmatter field${missingFields.length > 1 ? "s" : ""}: ${missingFields.join(", ")}`,
|
|
147
|
+
});
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
62
150
|
|
|
63
151
|
agents.push({
|
|
64
|
-
name
|
|
65
|
-
description
|
|
66
|
-
tools:
|
|
67
|
-
model: frontmatter.model,
|
|
152
|
+
name,
|
|
153
|
+
description,
|
|
154
|
+
tools: normalizeAgentTools(frontmatter.tools),
|
|
155
|
+
model: normalizeAgentModel(frontmatter.model),
|
|
68
156
|
systemPrompt: body,
|
|
69
157
|
source,
|
|
70
158
|
filePath,
|
|
71
159
|
});
|
|
72
160
|
}
|
|
73
161
|
|
|
74
|
-
|
|
162
|
+
agents.sort((left, right) => left.name.localeCompare(right.name));
|
|
163
|
+
errors.sort((left, right) => left.path.localeCompare(right.path));
|
|
164
|
+
|
|
165
|
+
return { agents, errors };
|
|
75
166
|
}
|
|
76
167
|
|
|
77
|
-
function isDirectory(
|
|
168
|
+
function isDirectory(candidatePath: string): boolean {
|
|
78
169
|
try {
|
|
79
|
-
return fs.statSync(
|
|
170
|
+
return fs.statSync(candidatePath).isDirectory();
|
|
80
171
|
} catch {
|
|
81
172
|
return false;
|
|
82
173
|
}
|
|
83
174
|
}
|
|
84
175
|
|
|
85
176
|
function findNearestProjectAgentsDir(cwd: string): string | null {
|
|
86
|
-
let currentDir = cwd;
|
|
177
|
+
let currentDir = normalizeFsPath(cwd);
|
|
178
|
+
|
|
87
179
|
while (true) {
|
|
88
|
-
const candidate = path.join(currentDir,
|
|
89
|
-
if (isDirectory(candidate))
|
|
180
|
+
const candidate = normalizeFsPath(path.join(currentDir, CONFIG_DIR_NAME, "agents"));
|
|
181
|
+
if (isDirectory(candidate)) {
|
|
182
|
+
return candidate;
|
|
183
|
+
}
|
|
90
184
|
|
|
91
185
|
const parentDir = path.dirname(currentDir);
|
|
92
|
-
if (parentDir === currentDir)
|
|
186
|
+
if (parentDir === currentDir) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
93
189
|
currentDir = parentDir;
|
|
94
190
|
}
|
|
95
191
|
}
|
|
96
192
|
|
|
97
193
|
export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult {
|
|
98
|
-
const userDir = path.join(getAgentDir(), "agents");
|
|
194
|
+
const userDir = normalizeFsPath(path.join(getAgentDir(), "agents"));
|
|
99
195
|
const projectAgentsDir = findNearestProjectAgentsDir(cwd);
|
|
100
196
|
|
|
101
|
-
const
|
|
102
|
-
const
|
|
197
|
+
const userDiscovery = scope === "project" ? { agents: [], errors: [] } : loadAgentsFromDir(userDir, "user");
|
|
198
|
+
const projectDiscovery =
|
|
199
|
+
scope === "user" || !projectAgentsDir
|
|
200
|
+
? { agents: [], errors: [] }
|
|
201
|
+
: loadAgentsFromDir(projectAgentsDir, "project");
|
|
103
202
|
|
|
104
203
|
const agentMap = new Map<string, AgentConfig>();
|
|
105
204
|
|
|
106
205
|
if (scope === "both") {
|
|
107
|
-
for (const agent of
|
|
108
|
-
for (const agent of
|
|
206
|
+
for (const agent of userDiscovery.agents) agentMap.set(agent.name, agent);
|
|
207
|
+
for (const agent of projectDiscovery.agents) agentMap.set(agent.name, agent);
|
|
109
208
|
} else if (scope === "user") {
|
|
110
|
-
for (const agent of
|
|
209
|
+
for (const agent of userDiscovery.agents) agentMap.set(agent.name, agent);
|
|
111
210
|
} else {
|
|
112
|
-
for (const agent of
|
|
211
|
+
for (const agent of projectDiscovery.agents) agentMap.set(agent.name, agent);
|
|
113
212
|
}
|
|
114
213
|
|
|
115
|
-
return {
|
|
214
|
+
return {
|
|
215
|
+
agents: Array.from(agentMap.values()).sort((left, right) => left.name.localeCompare(right.name)),
|
|
216
|
+
projectAgentsDir,
|
|
217
|
+
errors: [...userDiscovery.errors, ...projectDiscovery.errors].sort((left, right) =>
|
|
218
|
+
left.path.localeCompare(right.path),
|
|
219
|
+
),
|
|
220
|
+
};
|
|
116
221
|
}
|
|
117
222
|
|
|
118
223
|
export function formatAgentList(agents: AgentConfig[], maxItems: number): { text: string; remaining: number } {
|
|
@@ -120,8 +225,15 @@ export function formatAgentList(agents: AgentConfig[], maxItems: number): { text
|
|
|
120
225
|
const listed = agents.slice(0, maxItems);
|
|
121
226
|
const remaining = agents.length - listed.length;
|
|
122
227
|
return {
|
|
123
|
-
text: listed.map((
|
|
228
|
+
text: listed.map((agent) => `${agent.name} (${agent.source}): ${agent.description}`).join("; "),
|
|
124
229
|
remaining,
|
|
125
230
|
};
|
|
126
231
|
}
|
|
127
|
-
|
|
232
|
+
|
|
233
|
+
export function findDiscoveryErrorForAgent(
|
|
234
|
+
errors: AgentDiscoveryError[],
|
|
235
|
+
agentName: string,
|
|
236
|
+
): AgentDiscoveryError | undefined {
|
|
237
|
+
const expectedFileName = `${agentName}.md`.toLowerCase();
|
|
238
|
+
return errors.find((error) => path.basename(error.path).toLowerCase() === expectedFileName);
|
|
239
|
+
}
|