@promptbook/cli 0.112.0-30 → 0.112.0-32
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/esm/index.es.js +217 -51
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/runners/github-copilot/GitHubCopilotRunner.d.ts +19 -0
- package/esm/scripts/run-codex-prompts/runners/github-copilot/buildGitHubCopilotScript.d.ts +5 -0
- package/esm/src/_packages/components.index.d.ts +6 -0
- package/esm/src/_packages/types.index.d.ts +6 -0
- package/esm/src/book-2.0/agent-source/AgentReferenceResolver.d.ts +11 -0
- package/esm/src/book-2.0/agent-source/CreateAgentModelRequirementsOptions.d.ts +8 -0
- package/esm/src/book-2.0/agent-source/TeammateProfileResolver.d.ts +33 -0
- package/esm/src/book-2.0/agent-source/createTeamToolName.d.ts +7 -7
- package/esm/src/book-components/Chat/Chat/ChatActionsBar.d.ts +5 -0
- package/esm/src/book-components/Chat/Chat/ChatMessageItem.d.ts +17 -1
- package/esm/src/book-components/Chat/Chat/ChatMessageItem.test.d.ts +1 -1
- package/esm/src/book-components/Chat/Chat/ChatMessageList.d.ts +14 -0
- package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +290 -0
- package/esm/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +16 -0
- package/esm/src/book-components/Chat/Chat/renderAdvancedToolCallDetails.d.ts +4 -0
- package/esm/src/book-components/Chat/Chat/renderToolCallDetails.d.ts +9 -0
- package/esm/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +2 -1
- package/esm/src/book-components/Chat/MarkdownContent/MarkdownContent.test.d.ts +2 -0
- package/esm/src/book-components/Chat/hooks/useChatCompleteNotification.d.ts +18 -0
- package/esm/src/book-components/Chat/hooks/useChatCompleteNotification.test.d.ts +2 -0
- package/esm/src/book-components/Chat/types/ChatMessage.d.ts +77 -1
- package/esm/src/book-components/Chat/utils/formatToolCallDateTime.d.ts +37 -0
- package/esm/src/book-components/Chat/utils/formatToolCallLocalTime.d.ts +11 -0
- package/esm/src/book-components/Chat/utils/formatToolCallTranslationTemplate.d.ts +10 -0
- package/esm/src/book-components/Chat/utils/getChatMessageTimingDisplay.d.ts +5 -1
- package/esm/src/book-components/Chat/utils/getToolCallChipletInfo.d.ts +26 -1
- package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +26 -3
- package/esm/src/utils/toolCalls/mergeToolCalls.d.ts +1 -1
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +217 -51
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/runners/github-copilot/GitHubCopilotRunner.d.ts +19 -0
- package/umd/scripts/run-codex-prompts/runners/github-copilot/buildGitHubCopilotScript.d.ts +5 -0
- package/umd/src/_packages/components.index.d.ts +6 -0
- package/umd/src/_packages/types.index.d.ts +6 -0
- package/umd/src/book-2.0/agent-source/AgentReferenceResolver.d.ts +11 -0
- package/umd/src/book-2.0/agent-source/CreateAgentModelRequirementsOptions.d.ts +8 -0
- package/umd/src/book-2.0/agent-source/TeammateProfileResolver.d.ts +33 -0
- package/umd/src/book-2.0/agent-source/createTeamToolName.d.ts +7 -7
- package/umd/src/book-components/Chat/Chat/ChatActionsBar.d.ts +5 -0
- package/umd/src/book-components/Chat/Chat/ChatMessageItem.d.ts +17 -1
- package/umd/src/book-components/Chat/Chat/ChatMessageItem.test.d.ts +1 -1
- package/umd/src/book-components/Chat/Chat/ChatMessageList.d.ts +14 -0
- package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +290 -0
- package/umd/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +16 -0
- package/umd/src/book-components/Chat/Chat/renderAdvancedToolCallDetails.d.ts +4 -0
- package/umd/src/book-components/Chat/Chat/renderToolCallDetails.d.ts +9 -0
- package/umd/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +2 -1
- package/umd/src/book-components/Chat/MarkdownContent/MarkdownContent.test.d.ts +2 -0
- package/umd/src/book-components/Chat/hooks/useChatCompleteNotification.d.ts +18 -0
- package/umd/src/book-components/Chat/hooks/useChatCompleteNotification.test.d.ts +2 -0
- package/umd/src/book-components/Chat/types/ChatMessage.d.ts +77 -1
- package/umd/src/book-components/Chat/utils/formatToolCallDateTime.d.ts +37 -0
- package/umd/src/book-components/Chat/utils/formatToolCallLocalTime.d.ts +11 -0
- package/umd/src/book-components/Chat/utils/formatToolCallTranslationTemplate.d.ts +10 -0
- package/umd/src/book-components/Chat/utils/getChatMessageTimingDisplay.d.ts +5 -1
- package/umd/src/book-components/Chat/utils/getToolCallChipletInfo.d.ts +26 -1
- package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +26 -3
- package/umd/src/utils/toolCalls/mergeToolCalls.d.ts +1 -1
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -57,7 +57,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
57
57
|
* @generated
|
|
58
58
|
* @see https://github.com/webgptorg/promptbook
|
|
59
59
|
*/
|
|
60
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
60
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-32';
|
|
61
61
|
/**
|
|
62
62
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
63
63
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -2040,6 +2040,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
2040
2040
|
|
|
2041
2041
|
Runners:
|
|
2042
2042
|
- openai-codex: OpenAI Codex integration (requires --model)
|
|
2043
|
+
- github-copilot: GitHub Copilot CLI integration
|
|
2043
2044
|
- cline: Cline CLI integration
|
|
2044
2045
|
- claude-code: Claude Code integration
|
|
2045
2046
|
- opencode: Opencode integration
|
|
@@ -2052,7 +2053,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
2052
2053
|
- Dry-run mode to preview prompts
|
|
2053
2054
|
`));
|
|
2054
2055
|
command.option('--dry-run', 'Print unwritten prompts without executing', false);
|
|
2055
|
-
command.option('--agent <agent-name>', 'Select runner: openai-codex, cline, claude-code, opencode, gemini (required for non-dry-run)');
|
|
2056
|
+
command.option('--agent <agent-name>', 'Select runner: openai-codex, github-copilot, cline, claude-code, opencode, gemini (required for non-dry-run)');
|
|
2056
2057
|
command.option('--model <model>', spaceTrim$1(`
|
|
2057
2058
|
Model to use (required for openai-codex and gemini)
|
|
2058
2059
|
|
|
@@ -2072,6 +2073,7 @@ function $initializeCoderRunCommand(program) {
|
|
|
2072
2073
|
let agentName = undefined;
|
|
2073
2074
|
if (agent) {
|
|
2074
2075
|
if (agent === 'openai-codex' ||
|
|
2076
|
+
agent === 'github-copilot' ||
|
|
2075
2077
|
agent === 'cline' ||
|
|
2076
2078
|
agent === 'claude-code' ||
|
|
2077
2079
|
agent === 'opencode' ||
|
|
@@ -2079,12 +2081,12 @@ function $initializeCoderRunCommand(program) {
|
|
|
2079
2081
|
agentName = agent;
|
|
2080
2082
|
}
|
|
2081
2083
|
else {
|
|
2082
|
-
console.error(colors.red(`Invalid agent "${agent}". Must be one of: openai-codex, cline, claude-code, opencode, gemini`));
|
|
2084
|
+
console.error(colors.red(`Invalid agent "${agent}". Must be one of: openai-codex, github-copilot, cline, claude-code, opencode, gemini`));
|
|
2083
2085
|
return process.exit(1);
|
|
2084
2086
|
}
|
|
2085
2087
|
}
|
|
2086
2088
|
if (!agentName && !dryRun) {
|
|
2087
|
-
console.error(colors.red('You must choose an agent using --agent <openai-codex|cline|claude-code|opencode|gemini>'));
|
|
2089
|
+
console.error(colors.red('You must choose an agent using --agent <openai-codex|github-copilot|cline|claude-code|opencode|gemini>'));
|
|
2088
2090
|
return process.exit(1);
|
|
2089
2091
|
}
|
|
2090
2092
|
// Convert commander options to RunOptions format
|
|
@@ -21113,10 +21115,6 @@ class StyleCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
21113
21115
|
* Prefix used for TEAM tool names.
|
|
21114
21116
|
*/
|
|
21115
21117
|
const TEAM_TOOL_PREFIX = 'team_chat_';
|
|
21116
|
-
/**
|
|
21117
|
-
* Length of URL hash suffix appended to TEAM tool names.
|
|
21118
|
-
*/
|
|
21119
|
-
const TEAM_TOOL_HASH_LENGTH = 10;
|
|
21120
21118
|
/**
|
|
21121
21119
|
* Fallback normalized name when teammate label is empty.
|
|
21122
21120
|
*/
|
|
@@ -21133,20 +21131,19 @@ function normalizeTeammateToolNamePart(teammateLabel) {
|
|
|
21133
21131
|
return normalized || TEAM_TOOL_FALLBACK_NAME;
|
|
21134
21132
|
}
|
|
21135
21133
|
/**
|
|
21136
|
-
* Builds a deterministic TEAM tool name from teammate
|
|
21134
|
+
* Builds a deterministic TEAM tool name from the teammate label.
|
|
21137
21135
|
*
|
|
21138
|
-
* The
|
|
21139
|
-
*
|
|
21136
|
+
* The tool name is derived solely from the human-readable label so that it
|
|
21137
|
+
* remains stable and predictable regardless of internal technical identifiers.
|
|
21140
21138
|
*
|
|
21141
|
-
* @param
|
|
21142
|
-
* @param teammateLabel - Human-readable teammate label.
|
|
21143
|
-
* @returns
|
|
21139
|
+
* @param _teammateUrl - Canonical teammate URL (kept for API compatibility, not used).
|
|
21140
|
+
* @param teammateLabel - Human-readable teammate label used as the basis for the name.
|
|
21141
|
+
* @returns TEAM tool name derived from the label.
|
|
21144
21142
|
* @private internal utility of TEAM commitments and chat UI mapping
|
|
21145
21143
|
*/
|
|
21146
|
-
function createTeamToolName(
|
|
21144
|
+
function createTeamToolName(_teammateUrl, teammateLabel) {
|
|
21147
21145
|
const normalizedLabel = normalizeTeammateToolNamePart(teammateLabel);
|
|
21148
|
-
|
|
21149
|
-
return `${TEAM_TOOL_PREFIX}${normalizedLabel}_${hash}`;
|
|
21146
|
+
return `${TEAM_TOOL_PREFIX}${normalizedLabel}`;
|
|
21150
21147
|
}
|
|
21151
21148
|
|
|
21152
21149
|
const urlRegex = /https?:\/\/[^\s]+/gi;
|
|
@@ -21351,7 +21348,7 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
21351
21348
|
`);
|
|
21352
21349
|
}
|
|
21353
21350
|
applyToAgentModelRequirements(requirements, content) {
|
|
21354
|
-
var _a, _b;
|
|
21351
|
+
var _a, _b, _c;
|
|
21355
21352
|
const trimmedContent = content.trim();
|
|
21356
21353
|
if (!trimmedContent) {
|
|
21357
21354
|
return requirements;
|
|
@@ -21363,14 +21360,18 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
21363
21360
|
}
|
|
21364
21361
|
const agentName = ((_a = requirements._metadata) === null || _a === void 0 ? void 0 : _a.agentName) || 'Agent';
|
|
21365
21362
|
const existingTeammates = ((_b = requirements._metadata) === null || _b === void 0 ? void 0 : _b.teammates) || [];
|
|
21363
|
+
const preResolvedProfiles = (((_c = requirements._metadata) === null || _c === void 0 ? void 0 : _c.preResolvedTeammateProfiles) || {});
|
|
21366
21364
|
const resolvedTeammates = resolveTeamTeammateLabels(trimmedContent, teammates);
|
|
21367
21365
|
const teamEntries = resolvedTeammates.map((teammate) => {
|
|
21366
|
+
const profile = preResolvedProfiles[teammate.url];
|
|
21367
|
+
const resolvedLabel = (profile === null || profile === void 0 ? void 0 : profile.agentName) || teammate.label;
|
|
21368
21368
|
const existingTeammate = existingTeammates.find((entry) => entry.url === teammate.url);
|
|
21369
21369
|
return {
|
|
21370
21370
|
toolName: ((existingTeammate === null || existingTeammate === void 0 ? void 0 : existingTeammate.toolName) ||
|
|
21371
|
-
createTeamToolName(teammate.url,
|
|
21372
|
-
teammate,
|
|
21371
|
+
createTeamToolName(teammate.url, resolvedLabel)),
|
|
21372
|
+
teammate: { ...teammate, label: resolvedLabel },
|
|
21373
21373
|
agentName,
|
|
21374
|
+
description: (profile === null || profile === void 0 ? void 0 : profile.personaDescription) || null,
|
|
21374
21375
|
};
|
|
21375
21376
|
});
|
|
21376
21377
|
for (const entry of teamEntries) {
|
|
@@ -21382,9 +21383,12 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
21382
21383
|
if (updatedTools.some((tool) => tool.name === entry.toolName)) {
|
|
21383
21384
|
continue;
|
|
21384
21385
|
}
|
|
21386
|
+
const toolDescription = entry.description
|
|
21387
|
+
? `Consult teammate ${entry.teammate.label}\n${entry.description}`
|
|
21388
|
+
: `Consult teammate ${entry.teammate.label}`;
|
|
21385
21389
|
updatedTools.push({
|
|
21386
21390
|
name: entry.toolName,
|
|
21387
|
-
description:
|
|
21391
|
+
description: toolDescription,
|
|
21388
21392
|
parameters: {
|
|
21389
21393
|
type: 'object',
|
|
21390
21394
|
properties: {
|
|
@@ -21413,8 +21417,7 @@ class TeamCommitmentDefinition extends BaseCommitmentDefinition {
|
|
|
21413
21417
|
toolName: entry.toolName,
|
|
21414
21418
|
});
|
|
21415
21419
|
}
|
|
21416
|
-
const
|
|
21417
|
-
const teamSystemMessage = this.createSystemMessageSection('Teammates:', buildTeamSystemMessageBody(teamOverviewText, teamEntries));
|
|
21420
|
+
const teamSystemMessage = this.createSystemMessageSection('Teammates:', buildTeamSystemMessageBody(teamEntries));
|
|
21418
21421
|
return this.appendToSystemMessage({
|
|
21419
21422
|
...requirements,
|
|
21420
21423
|
tools: updatedTools,
|
|
@@ -21451,25 +21454,24 @@ function resolveTeamTeammateLabels(teamContent, teammates) {
|
|
|
21451
21454
|
};
|
|
21452
21455
|
});
|
|
21453
21456
|
}
|
|
21454
|
-
/**
|
|
21455
|
-
* Rewrites TEAM commitment content into a URL-free teammate overview text.
|
|
21456
|
-
*/
|
|
21457
|
-
function createTeamOverviewText(teamContent, teamEntries) {
|
|
21458
|
-
let overviewText = teamContent;
|
|
21459
|
-
for (const entry of teamEntries) {
|
|
21460
|
-
overviewText = overviewText.split(entry.teammate.url).join(entry.teammate.label);
|
|
21461
|
-
}
|
|
21462
|
-
return overviewText.trim();
|
|
21463
|
-
}
|
|
21464
21457
|
/**
|
|
21465
21458
|
* Builds the textual TEAM section body for the final system message.
|
|
21459
|
+
*
|
|
21460
|
+
* Each teammate is listed with its tool name and, when available, a one-line description.
|
|
21461
|
+
* Uses `spaceTrim` to ensure consistent whitespace and indentation.
|
|
21466
21462
|
*/
|
|
21467
|
-
function buildTeamSystemMessageBody(
|
|
21468
|
-
const
|
|
21469
|
-
|
|
21470
|
-
|
|
21471
|
-
|
|
21472
|
-
|
|
21463
|
+
function buildTeamSystemMessageBody(teamEntries) {
|
|
21464
|
+
const lines = teamEntries.map((entry, index) => {
|
|
21465
|
+
const toolLine = `${index + 1}) ${entry.teammate.label} tool \`${entry.toolName}\``;
|
|
21466
|
+
if (!entry.description) {
|
|
21467
|
+
return toolLine;
|
|
21468
|
+
}
|
|
21469
|
+
return spaceTrim$1(`
|
|
21470
|
+
${toolLine}
|
|
21471
|
+
${entry.description}
|
|
21472
|
+
`);
|
|
21473
|
+
});
|
|
21474
|
+
return lines.join('\n');
|
|
21473
21475
|
}
|
|
21474
21476
|
/**
|
|
21475
21477
|
* Registers tool function and title for a teammate tool.
|
|
@@ -39117,7 +39119,7 @@ function getSafeReferenceCommitmentFallback(commitmentType, originalContent) {
|
|
|
39117
39119
|
* @private @@@
|
|
39118
39120
|
*/
|
|
39119
39121
|
async function createAgentModelRequirementsWithCommitments(agentSource, modelName, options) {
|
|
39120
|
-
var _a;
|
|
39122
|
+
var _a, _b, _c;
|
|
39121
39123
|
const agentReferenceResolver = options === null || options === void 0 ? void 0 : options.agentReferenceResolver;
|
|
39122
39124
|
// Parse the agent source to extract commitments
|
|
39123
39125
|
const parseResult = parseAgentSourceWithCommitments(agentSource);
|
|
@@ -39185,6 +39187,36 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
39185
39187
|
if (commitment.type === 'CLOSED' && i !== filteredCommitments.length - 1) {
|
|
39186
39188
|
continue;
|
|
39187
39189
|
}
|
|
39190
|
+
// For TEAM commitments, pre-resolve teammate profiles if a resolver is provided
|
|
39191
|
+
// and store them in metadata before the commitment is applied.
|
|
39192
|
+
const profileResolver = (_a = options === null || options === void 0 ? void 0 : options.teammateProfileResolver) !== null && _a !== void 0 ? _a : options === null || options === void 0 ? void 0 : options.agentReferenceResolver;
|
|
39193
|
+
if (commitment.type === 'TEAM' && (profileResolver === null || profileResolver === void 0 ? void 0 : profileResolver.resolveTeammateProfile)) {
|
|
39194
|
+
try {
|
|
39195
|
+
const parsedTeammates = parseTeamCommitmentContent(commitmentContent, { strict: false });
|
|
39196
|
+
const preResolved = {
|
|
39197
|
+
...(_b = requirements._metadata) === null || _b === void 0 ? void 0 : _b.preResolvedTeammateProfiles,
|
|
39198
|
+
};
|
|
39199
|
+
for (const teammate of parsedTeammates) {
|
|
39200
|
+
if (preResolved[teammate.url]) {
|
|
39201
|
+
continue;
|
|
39202
|
+
}
|
|
39203
|
+
const profile = await profileResolver.resolveTeammateProfile(teammate.url);
|
|
39204
|
+
if (profile) {
|
|
39205
|
+
preResolved[teammate.url] = profile;
|
|
39206
|
+
}
|
|
39207
|
+
}
|
|
39208
|
+
requirements = {
|
|
39209
|
+
...requirements,
|
|
39210
|
+
_metadata: {
|
|
39211
|
+
...requirements._metadata,
|
|
39212
|
+
preResolvedTeammateProfiles: preResolved,
|
|
39213
|
+
},
|
|
39214
|
+
};
|
|
39215
|
+
}
|
|
39216
|
+
catch (error) {
|
|
39217
|
+
console.warn('Failed to pre-resolve teammate profiles for TEAM commitment:', error);
|
|
39218
|
+
}
|
|
39219
|
+
}
|
|
39188
39220
|
const definition = getCommitmentDefinition(commitment.type);
|
|
39189
39221
|
if (definition) {
|
|
39190
39222
|
try {
|
|
@@ -39280,7 +39312,7 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
39280
39312
|
// Add example interactions to the system message
|
|
39281
39313
|
const examples = [];
|
|
39282
39314
|
// 1. Initial message as an example agent response
|
|
39283
|
-
const initialMessage = (
|
|
39315
|
+
const initialMessage = (_c = parseResult.commitments.find((c) => c.type === 'INITIAL MESSAGE')) === null || _c === void 0 ? void 0 : _c.content;
|
|
39284
39316
|
if (initialMessage) {
|
|
39285
39317
|
examples.push(`Agent: ${initialMessage}`);
|
|
39286
39318
|
}
|
|
@@ -40733,6 +40765,7 @@ async function findRefactorCandidates() {
|
|
|
40733
40765
|
const { selectedEmojis } = await getFreshPromptEmojiTags({
|
|
40734
40766
|
count: candidatesToWrite.length,
|
|
40735
40767
|
rootDir,
|
|
40768
|
+
tagPrefix: '🧹',
|
|
40736
40769
|
});
|
|
40737
40770
|
await mkdir(promptsDir, { recursive: true });
|
|
40738
40771
|
const createdPrompts = [];
|
|
@@ -40745,7 +40778,7 @@ async function findRefactorCandidates() {
|
|
|
40745
40778
|
if (!selectedEmoji) {
|
|
40746
40779
|
throw new Error(`Missing emoji for prompt candidate #${index + 1}`);
|
|
40747
40780
|
}
|
|
40748
|
-
const emojiTag = formatPromptEmojiTag(selectedEmoji);
|
|
40781
|
+
const emojiTag = formatPromptEmojiTag(selectedEmoji, '🧹');
|
|
40749
40782
|
const promptContent = buildPromptContent(candidate, emojiTag);
|
|
40750
40783
|
await writeFile(promptPath, promptContent, 'utf-8');
|
|
40751
40784
|
createdPrompts.push(filename);
|
|
@@ -40791,7 +40824,7 @@ function buildPromptGuidance(candidate) {
|
|
|
40791
40824
|
if (counts.entityCount !== null && counts.maxEntities !== null) {
|
|
40792
40825
|
guidance.push(`- The file defines too many responsibilities (${counts.entityCount} in single file)`, ` - Keep in mind the Single Responsibility Principle (SRP)`, ` - Consider breaking it down into smaller, focused modules or components.`);
|
|
40793
40826
|
}
|
|
40794
|
-
guidance.push('- Purpose of this refactoring is to improve code maintainability and readability.', '- Look at the internal structure, the usage and also surrounding code to understand how to best refactor this file.', '- Consider breaking down large functions into smaller, more manageable ones, removing any redundant code, and ensuring that the file adheres to the project coding standards.', '- After the refactoring, ensure that (1) `npm run test-name-discrepancies` and (2) `npm run test-package-generation` are passing successfully.', ' 1. All the things you have moved to new files should correspond the thing in the file with the file name, for example `MyComponent.tsx` should export `MyComponent`.', ' 2. All the things you have moved to new files but are private things to the outside world should have `@private function of TheMainThing` JSDoc comment.', '- Keep in mind DRY *(Do not repeat yourself)* and SOLID principles while refactoring.', '- **Do not change the external behavior** of the code. Focus solely on improving the internal structure and organization of the code.');
|
|
40827
|
+
guidance.push('- Purpose of this refactoring is to improve code maintainability and readability.', '- Look at the internal structure, the usage and also surrounding code to understand how to best refactor this file.', '- Consider breaking down large functions into smaller, more manageable ones, removing any redundant code, and ensuring that the file adheres to the project coding standards.', '- After the refactoring, ensure that (1) `npm run test-name-discrepancies` and (2) `npm run test-package-generation` are passing successfully.', ' 1. All the things you have moved to new files should correspond the thing in the file with the file name, for example `MyComponent.tsx` should export `MyComponent`.', ' 2. All the things you have moved to new files but are private things to the outside world should have `@private function of TheMainThing` JSDoc comment.', '- Keep in mind DRY *(Do not repeat yourself)* and SOLID principles while refactoring.', '- **Do not change the external behavior** of the code. Focus solely on improving the internal structure and organization of the code.', '- Before you start refactoring, make sure to read the code carefully and understand its current structure and functionality. Do a analysis of the current functionality before you start.');
|
|
40795
40828
|
// <- TODO: Leverage `spaceTrim` here
|
|
40796
40829
|
return guidance;
|
|
40797
40830
|
}
|
|
@@ -41043,6 +41076,7 @@ function parseRunOptions(args) {
|
|
|
41043
41076
|
if (agentValue) {
|
|
41044
41077
|
const value = agentValue;
|
|
41045
41078
|
if (value === 'openai-codex' ||
|
|
41079
|
+
value === 'github-copilot' ||
|
|
41046
41080
|
value === 'cline' ||
|
|
41047
41081
|
value === 'claude-code' ||
|
|
41048
41082
|
value === 'opencode' ||
|
|
@@ -41059,7 +41093,7 @@ function parseRunOptions(args) {
|
|
|
41059
41093
|
const autoMigrate = args.includes('--auto-migrate');
|
|
41060
41094
|
const allowDestructiveAutoMigrate = args.includes('--allow-destructive-auto-migrate');
|
|
41061
41095
|
if (!agentName && !dryRun) {
|
|
41062
|
-
exitWithUsageError('You must choose an agent using --agent <openai-codex|cline|claude-code|opencode|gemini>');
|
|
41096
|
+
exitWithUsageError('You must choose an agent using --agent <openai-codex|github-copilot|cline|claude-code|opencode|gemini>');
|
|
41063
41097
|
}
|
|
41064
41098
|
return {
|
|
41065
41099
|
dryRun,
|
|
@@ -43488,6 +43522,7 @@ function createCodingContext() {
|
|
|
43488
43522
|
- Keep small responsibilities of functions and classes, avoid creating big functions or classes that do many things.
|
|
43489
43523
|
- When throwing errors, throw [branded errors](src/errors) and use \`spaceTrim\` utility to write clear and well-formatted multilie detailed error messages.
|
|
43490
43524
|
- Format errors as markdown, for example \`variabiles\` should be in backticks, important notes can be in bold, etc.
|
|
43525
|
+
- Constants should be always \`UPPER_SNAKE_CASE\`
|
|
43491
43526
|
- When writing multiline strings, use \`spaceTrim\` utility
|
|
43492
43527
|
- DO only the change described here above DO not add any additional features or make any additional changes that are not described in the prompt.
|
|
43493
43528
|
- If you find some critical issue that is not described in the prompt, report it to the file \`./AGENT_REPORT.md\` on the root of the project
|
|
@@ -43851,6 +43886,60 @@ class GeminiRunner {
|
|
|
43851
43886
|
}
|
|
43852
43887
|
}
|
|
43853
43888
|
|
|
43889
|
+
/**
|
|
43890
|
+
* Builds the shell script that runs GitHub Copilot CLI with the prompt and coding context.
|
|
43891
|
+
*/
|
|
43892
|
+
function buildGitHubCopilotScript(options) {
|
|
43893
|
+
const delimiter = 'GITHUB_COPILOT_PROMPT';
|
|
43894
|
+
const projectPath = toPosixPath(options.projectPath);
|
|
43895
|
+
const modelArgument = options.model ? ` --model ${options.model}` : '';
|
|
43896
|
+
return spaceTrim((block) => `
|
|
43897
|
+
cd "${projectPath}"
|
|
43898
|
+
|
|
43899
|
+
copilot -p "$(cat <<'${delimiter}'
|
|
43900
|
+
|
|
43901
|
+
${block(options.prompt)}
|
|
43902
|
+
|
|
43903
|
+
${block(createCodingContext())}
|
|
43904
|
+
|
|
43905
|
+
${delimiter}
|
|
43906
|
+
)" \
|
|
43907
|
+
--yolo \
|
|
43908
|
+
--no-ask-user \
|
|
43909
|
+
--no-color \
|
|
43910
|
+
--output-format json \
|
|
43911
|
+
--stream off${modelArgument}
|
|
43912
|
+
`);
|
|
43913
|
+
}
|
|
43914
|
+
|
|
43915
|
+
/**
|
|
43916
|
+
* Runs prompts via the GitHub Copilot CLI.
|
|
43917
|
+
*/
|
|
43918
|
+
class GitHubCopilotRunner {
|
|
43919
|
+
/**
|
|
43920
|
+
* Creates a new GitHub Copilot runner.
|
|
43921
|
+
*/
|
|
43922
|
+
constructor(options) {
|
|
43923
|
+
this.options = options;
|
|
43924
|
+
this.name = 'github-copilot';
|
|
43925
|
+
}
|
|
43926
|
+
/**
|
|
43927
|
+
* Runs the prompt using GitHub Copilot CLI.
|
|
43928
|
+
*/
|
|
43929
|
+
async runPrompt(options) {
|
|
43930
|
+
const scriptContent = buildGitHubCopilotScript({
|
|
43931
|
+
prompt: options.prompt,
|
|
43932
|
+
projectPath: options.projectPath,
|
|
43933
|
+
model: this.options.model,
|
|
43934
|
+
});
|
|
43935
|
+
await $runGoScript({
|
|
43936
|
+
scriptPath: options.scriptPath,
|
|
43937
|
+
scriptContent,
|
|
43938
|
+
});
|
|
43939
|
+
return { usage: UNCERTAIN_USAGE };
|
|
43940
|
+
}
|
|
43941
|
+
}
|
|
43942
|
+
|
|
43854
43943
|
/**
|
|
43855
43944
|
* Maximum number of output characters included in thrown error messages.
|
|
43856
43945
|
*/
|
|
@@ -44588,6 +44677,7 @@ const DEFAULT_CODEX_MODEL = 'gpt-5.2-codex';
|
|
|
44588
44677
|
const CLINE_MODEL = 'gemini:gemini-3-flash-preview';
|
|
44589
44678
|
const RUNNER_LABELS = {
|
|
44590
44679
|
'openai-codex': 'OpenAI Codex',
|
|
44680
|
+
'github-copilot': 'GitHub Copilot',
|
|
44591
44681
|
cline: 'Cline',
|
|
44592
44682
|
'claude-code': 'Claude Code',
|
|
44593
44683
|
opencode: 'Opencode',
|
|
@@ -44603,6 +44693,9 @@ function getRunnerMetadata(options, actualModel) {
|
|
|
44603
44693
|
if (options.agentName === 'openai-codex') {
|
|
44604
44694
|
modelName = actualModel;
|
|
44605
44695
|
}
|
|
44696
|
+
else if (options.agentName === 'github-copilot') {
|
|
44697
|
+
modelName = actualModel;
|
|
44698
|
+
}
|
|
44606
44699
|
else if (options.agentName === 'gemini') {
|
|
44607
44700
|
modelName = actualModel;
|
|
44608
44701
|
}
|
|
@@ -44640,8 +44733,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
44640
44733
|
return;
|
|
44641
44734
|
}
|
|
44642
44735
|
let runner;
|
|
44643
|
-
let
|
|
44644
|
-
let actualGeminiModel;
|
|
44736
|
+
let actualRunnerModel;
|
|
44645
44737
|
const agentName = options.agentName;
|
|
44646
44738
|
if (!agentName) {
|
|
44647
44739
|
throw new Error('Missing --agent in non-dry run mode');
|
|
@@ -44668,7 +44760,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
44668
44760
|
else {
|
|
44669
44761
|
modelToUse = options.model;
|
|
44670
44762
|
}
|
|
44671
|
-
|
|
44763
|
+
actualRunnerModel = modelToUse;
|
|
44672
44764
|
runner = new OpenAiCodexRunner({
|
|
44673
44765
|
codexCommand: 'codex',
|
|
44674
44766
|
model: modelToUse,
|
|
@@ -44685,6 +44777,13 @@ async function runCodexPrompts(providedOptions) {
|
|
|
44685
44777
|
model: CLINE_MODEL,
|
|
44686
44778
|
});
|
|
44687
44779
|
}
|
|
44780
|
+
else if (agentName === 'github-copilot') {
|
|
44781
|
+
const modelToUse = options.model === 'default' ? undefined : options.model;
|
|
44782
|
+
actualRunnerModel = modelToUse;
|
|
44783
|
+
runner = new GitHubCopilotRunner({
|
|
44784
|
+
model: modelToUse,
|
|
44785
|
+
});
|
|
44786
|
+
}
|
|
44688
44787
|
else if (agentName === 'claude-code') {
|
|
44689
44788
|
runner = new ClaudeCodeRunner();
|
|
44690
44789
|
}
|
|
@@ -44709,7 +44808,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
44709
44808
|
else {
|
|
44710
44809
|
modelToUse = options.model;
|
|
44711
44810
|
}
|
|
44712
|
-
|
|
44811
|
+
actualRunnerModel = modelToUse;
|
|
44713
44812
|
runner = new GeminiRunner({
|
|
44714
44813
|
model: modelToUse,
|
|
44715
44814
|
});
|
|
@@ -44718,7 +44817,7 @@ async function runCodexPrompts(providedOptions) {
|
|
|
44718
44817
|
throw new Error(`Unknown agent: ${agentName}`);
|
|
44719
44818
|
}
|
|
44720
44819
|
console.info(colors.green(`Running prompts with ${runner.name}`));
|
|
44721
|
-
const runnerMetadata = getRunnerMetadata(options,
|
|
44820
|
+
const runnerMetadata = getRunnerMetadata(options, actualRunnerModel);
|
|
44722
44821
|
let hasShownUpcomingTasks = false;
|
|
44723
44822
|
let hasWaitedForStart = false;
|
|
44724
44823
|
while (just(true)) {
|
|
@@ -45465,13 +45564,23 @@ function getToolCallIdentity(toolCall) {
|
|
|
45465
45564
|
*/
|
|
45466
45565
|
function mergeToolCalls(existingToolCalls, incomingToolCalls) {
|
|
45467
45566
|
if (!existingToolCalls || existingToolCalls.length === 0) {
|
|
45468
|
-
return incomingToolCalls ? [...incomingToolCalls] : [];
|
|
45567
|
+
return incomingToolCalls ? deduplicatePreparationToolCalls([...incomingToolCalls]) : [];
|
|
45469
45568
|
}
|
|
45470
45569
|
if (!incomingToolCalls || incomingToolCalls.length === 0) {
|
|
45471
45570
|
return [...existingToolCalls];
|
|
45472
45571
|
}
|
|
45473
45572
|
const mergedToolCalls = [...existingToolCalls];
|
|
45474
45573
|
for (const incomingToolCall of incomingToolCalls) {
|
|
45574
|
+
if (isAssistantPreparationToolCall(incomingToolCall)) {
|
|
45575
|
+
// A new preparation phase always replaces any previous assistant_preparation tool
|
|
45576
|
+
// call, regardless of phase argument, so only one chip is ever shown at a time.
|
|
45577
|
+
const existingPreparationIndex = mergedToolCalls.findIndex(isAssistantPreparationToolCall);
|
|
45578
|
+
if (existingPreparationIndex !== -1) {
|
|
45579
|
+
mergedToolCalls.splice(existingPreparationIndex, 1);
|
|
45580
|
+
}
|
|
45581
|
+
mergedToolCalls.push(incomingToolCall);
|
|
45582
|
+
continue;
|
|
45583
|
+
}
|
|
45475
45584
|
const incomingIdentity = getToolCallIdentity(incomingToolCall);
|
|
45476
45585
|
const existingIndex = mergedToolCalls.findIndex((existingToolCall) => getToolCallIdentity(existingToolCall) === incomingIdentity);
|
|
45477
45586
|
if (existingIndex === -1) {
|
|
@@ -45583,6 +45692,30 @@ function serializeValueForMerge(value) {
|
|
|
45583
45692
|
return String(value);
|
|
45584
45693
|
}
|
|
45585
45694
|
}
|
|
45695
|
+
/**
|
|
45696
|
+
* Ensures at most one `assistant_preparation` tool call survives in the list,
|
|
45697
|
+
* keeping the last occurrence so the most recent preparation phase is shown.
|
|
45698
|
+
*
|
|
45699
|
+
* @param toolCalls - Mutable list to deduplicate in-place.
|
|
45700
|
+
* @returns The same array after removing redundant preparation entries.
|
|
45701
|
+
* @private helper of `mergeToolCalls`
|
|
45702
|
+
*/
|
|
45703
|
+
function deduplicatePreparationToolCalls(toolCalls) {
|
|
45704
|
+
let lastPreparationIndex = -1;
|
|
45705
|
+
for (let index = toolCalls.length - 1; index >= 0; index--) {
|
|
45706
|
+
if (!isAssistantPreparationToolCall(toolCalls[index])) {
|
|
45707
|
+
continue;
|
|
45708
|
+
}
|
|
45709
|
+
if (lastPreparationIndex === -1) {
|
|
45710
|
+
lastPreparationIndex = index;
|
|
45711
|
+
}
|
|
45712
|
+
else {
|
|
45713
|
+
// Remove earlier duplicate — keep only the last (most recent) one.
|
|
45714
|
+
toolCalls.splice(index, 1);
|
|
45715
|
+
}
|
|
45716
|
+
}
|
|
45717
|
+
return toolCalls;
|
|
45718
|
+
}
|
|
45586
45719
|
|
|
45587
45720
|
/**
|
|
45588
45721
|
* Gets all tool titles provided by all commitments
|
|
@@ -47749,6 +47882,7 @@ class SelfLearningManager {
|
|
|
47749
47882
|
|
|
47750
47883
|
- Decide what the agent should learn from this interaction.
|
|
47751
47884
|
- Append new commitments at the end of the agent source.
|
|
47885
|
+
- Return only newly learned commitments, never repeat commitments that are already present.
|
|
47752
47886
|
- Do not modify the current agent source, just return new commitments (KNOWLEDGE, RULE, etc.).
|
|
47753
47887
|
- If there is nothing new to learn, return empty book code block
|
|
47754
47888
|
- Wrap the commitments in a book code block.
|
|
@@ -47801,10 +47935,42 @@ class SelfLearningManager {
|
|
|
47801
47935
|
*/
|
|
47802
47936
|
appendToAgentSource(section) {
|
|
47803
47937
|
const currentSource = this.options.getAgentSource();
|
|
47804
|
-
const
|
|
47938
|
+
const normalizedSection = normalizeBookSection(section);
|
|
47939
|
+
if (!normalizedSection) {
|
|
47940
|
+
return;
|
|
47941
|
+
}
|
|
47942
|
+
if (containsNormalizedBookSection(currentSource, normalizedSection)) {
|
|
47943
|
+
return;
|
|
47944
|
+
}
|
|
47945
|
+
const newSource = padBook(validateBook(`${normalizeBookSection(currentSource)}\n\n${normalizedSection}`));
|
|
47805
47946
|
this.options.updateAgentSource(newSource);
|
|
47806
47947
|
}
|
|
47807
47948
|
}
|
|
47949
|
+
/**
|
|
47950
|
+
* Normalizes one book fragment for deduplication and append composition.
|
|
47951
|
+
*
|
|
47952
|
+
* @param section Raw fragment from self-learning workflow.
|
|
47953
|
+
* @returns Trimmed fragment, or empty string when nothing remains.
|
|
47954
|
+
* @private function of Agent
|
|
47955
|
+
*/
|
|
47956
|
+
function normalizeBookSection(section) {
|
|
47957
|
+
return spaceTrim$1(section).replace(/\r\n/g, '\n');
|
|
47958
|
+
}
|
|
47959
|
+
/**
|
|
47960
|
+
* Checks whether one normalized fragment already exists inside the current source.
|
|
47961
|
+
*
|
|
47962
|
+
* @param agentSource Current source.
|
|
47963
|
+
* @param normalizedSection Candidate fragment expected to be normalized first.
|
|
47964
|
+
* @returns True when appending would duplicate an existing fragment.
|
|
47965
|
+
* @private function of Agent
|
|
47966
|
+
*/
|
|
47967
|
+
function containsNormalizedBookSection(agentSource, normalizedSection) {
|
|
47968
|
+
if (!normalizedSection) {
|
|
47969
|
+
return true;
|
|
47970
|
+
}
|
|
47971
|
+
const normalizedSource = normalizeBookSection(agentSource);
|
|
47972
|
+
return normalizedSource.includes(normalizedSection);
|
|
47973
|
+
}
|
|
47808
47974
|
/**
|
|
47809
47975
|
* Determines whether the interaction runs in OpenAI-compatible JSON schema mode.
|
|
47810
47976
|
*
|