@aramassa/ai-rules 0.4.3 → 0.5.1
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/artifact/chatmodes/Planning.md +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +230 -5
- package/dist/recipeValidator.d.ts +1 -0
- package/dist/recipeValidator.d.ts.map +1 -1
- package/dist/recipeValidator.js +36 -0
- package/dist/utils/gitActions.d.ts +25 -0
- package/dist/utils/gitActions.d.ts.map +1 -0
- package/dist/utils/gitActions.js +88 -0
- package/package.json +1 -1
- package/schemas/recipe.schema.json +47 -0
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAosBA;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,MAAY,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BnB"}
|
package/dist/cli.js
CHANGED
|
@@ -8,9 +8,11 @@ import require$$1 from 'node:child_process';
|
|
|
8
8
|
import require$$2 from 'node:path';
|
|
9
9
|
import require$$3$1 from 'node:fs';
|
|
10
10
|
import require$$4 from 'node:process';
|
|
11
|
+
import readline from 'readline';
|
|
11
12
|
import { fileURLToPath } from 'url';
|
|
12
13
|
import { createHash } from 'crypto';
|
|
13
14
|
import { homedir } from 'os';
|
|
15
|
+
import { execSync } from 'child_process';
|
|
14
16
|
|
|
15
17
|
/******************************************************************************
|
|
16
18
|
Copyright (c) Microsoft Corporation.
|
|
@@ -17810,6 +17812,15 @@ class RecipeValidator {
|
|
|
17810
17812
|
return commonMistakeProps.includes(property);
|
|
17811
17813
|
}
|
|
17812
17814
|
checkCommonMistakes(recipeData, result) {
|
|
17815
|
+
// Validate pre-action if present
|
|
17816
|
+
if (recipeData['pre-action']) {
|
|
17817
|
+
if (!Array.isArray(recipeData['pre-action'])) {
|
|
17818
|
+
result.warnings.push('Warning: Pre-action should be an array');
|
|
17819
|
+
}
|
|
17820
|
+
else {
|
|
17821
|
+
this.validatePreActions(recipeData['pre-action'], result);
|
|
17822
|
+
}
|
|
17823
|
+
}
|
|
17813
17824
|
// Check for properties that should be under filters or frontmatter
|
|
17814
17825
|
if (Array.isArray(recipeData.recipe)) {
|
|
17815
17826
|
recipeData.recipe.forEach((item, index) => {
|
|
@@ -17847,6 +17858,33 @@ class RecipeValidator {
|
|
|
17847
17858
|
}
|
|
17848
17859
|
});
|
|
17849
17860
|
}
|
|
17861
|
+
validatePreActions(preActions, result) {
|
|
17862
|
+
for (let i = 0; i < preActions.length; i++) {
|
|
17863
|
+
const action = preActions[i];
|
|
17864
|
+
if (!action || typeof action !== 'object') {
|
|
17865
|
+
result.warnings.push(`Warning: Pre-action item ${i + 1} should be an object`);
|
|
17866
|
+
continue;
|
|
17867
|
+
}
|
|
17868
|
+
if (!action.type) {
|
|
17869
|
+
result.warnings.push(`Warning: Pre-action item ${i + 1} is missing required 'type' field`);
|
|
17870
|
+
continue;
|
|
17871
|
+
}
|
|
17872
|
+
if (action.type === 'git-pull') {
|
|
17873
|
+
if (!action.path) {
|
|
17874
|
+
result.warnings.push(`Warning: Git-pull action ${i + 1} is missing required 'path' field`);
|
|
17875
|
+
}
|
|
17876
|
+
if (action.depth !== undefined && typeof action.depth !== 'number') {
|
|
17877
|
+
result.warnings.push(`Warning: Git-pull action ${i + 1}: 'depth' should be a number`);
|
|
17878
|
+
}
|
|
17879
|
+
if (action.depth !== undefined && action.depth < 1) {
|
|
17880
|
+
result.warnings.push(`Warning: Git-pull action ${i + 1}: 'depth' should be at least 1`);
|
|
17881
|
+
}
|
|
17882
|
+
}
|
|
17883
|
+
else {
|
|
17884
|
+
result.warnings.push(`Warning: Pre-action item ${i + 1} has unknown type: ${action.type}`);
|
|
17885
|
+
}
|
|
17886
|
+
}
|
|
17887
|
+
}
|
|
17850
17888
|
}
|
|
17851
17889
|
// Singleton instance
|
|
17852
17890
|
let validatorInstance = null;
|
|
@@ -17858,6 +17896,92 @@ async function getRecipeValidator() {
|
|
|
17858
17896
|
return validatorInstance;
|
|
17859
17897
|
}
|
|
17860
17898
|
|
|
17899
|
+
/**
|
|
17900
|
+
* Executes git pull in the specified repository
|
|
17901
|
+
* @param options - Configuration for the git pull operation
|
|
17902
|
+
* @param debugLogger - Optional debug logger
|
|
17903
|
+
* @returns Result of the git pull operation
|
|
17904
|
+
*/
|
|
17905
|
+
async function executeGitPull(options, debugLogger) {
|
|
17906
|
+
try {
|
|
17907
|
+
// Verify it's a git repository
|
|
17908
|
+
const isRepo = await verifyGitRepository(options.path);
|
|
17909
|
+
if (!isRepo) {
|
|
17910
|
+
return {
|
|
17911
|
+
success: false,
|
|
17912
|
+
message: "Path is not a git repository",
|
|
17913
|
+
updated: false,
|
|
17914
|
+
};
|
|
17915
|
+
}
|
|
17916
|
+
// Switch to target branch if specified
|
|
17917
|
+
if (options.branch) {
|
|
17918
|
+
try {
|
|
17919
|
+
debugLogger?.log(`Switching to branch: ${options.branch}`);
|
|
17920
|
+
execSync(`git checkout ${options.branch}`, {
|
|
17921
|
+
cwd: options.path,
|
|
17922
|
+
encoding: "utf-8",
|
|
17923
|
+
stdio: "pipe",
|
|
17924
|
+
});
|
|
17925
|
+
}
|
|
17926
|
+
catch (error) {
|
|
17927
|
+
return {
|
|
17928
|
+
success: false,
|
|
17929
|
+
message: `Failed to checkout branch ${options.branch}: ${error.message}`,
|
|
17930
|
+
updated: false,
|
|
17931
|
+
};
|
|
17932
|
+
}
|
|
17933
|
+
}
|
|
17934
|
+
// Build git pull command
|
|
17935
|
+
let command = "git pull";
|
|
17936
|
+
if (options.depth) {
|
|
17937
|
+
command += ` --depth=${options.depth}`;
|
|
17938
|
+
}
|
|
17939
|
+
debugLogger?.log(`Executing: ${command} in ${options.path}`);
|
|
17940
|
+
// Execute git pull
|
|
17941
|
+
const output = execSync(command, {
|
|
17942
|
+
cwd: options.path,
|
|
17943
|
+
encoding: "utf-8",
|
|
17944
|
+
stdio: "pipe",
|
|
17945
|
+
});
|
|
17946
|
+
const updated = !output.includes("Already up to date");
|
|
17947
|
+
return {
|
|
17948
|
+
success: true,
|
|
17949
|
+
message: output.trim(),
|
|
17950
|
+
updated,
|
|
17951
|
+
};
|
|
17952
|
+
}
|
|
17953
|
+
catch (error) {
|
|
17954
|
+
return {
|
|
17955
|
+
success: false,
|
|
17956
|
+
message: error.message || "Unknown error",
|
|
17957
|
+
updated: false,
|
|
17958
|
+
};
|
|
17959
|
+
}
|
|
17960
|
+
}
|
|
17961
|
+
/**
|
|
17962
|
+
* Verifies that the given path is a git repository
|
|
17963
|
+
* @param repoPath - Path to verify
|
|
17964
|
+
* @returns True if the path is a git repository, false otherwise
|
|
17965
|
+
*/
|
|
17966
|
+
async function verifyGitRepository(repoPath) {
|
|
17967
|
+
try {
|
|
17968
|
+
const gitDir = path.join(repoPath, ".git");
|
|
17969
|
+
if (!fsSync.existsSync(gitDir)) {
|
|
17970
|
+
return false;
|
|
17971
|
+
}
|
|
17972
|
+
// Verify with git command
|
|
17973
|
+
execSync("git rev-parse --git-dir", {
|
|
17974
|
+
cwd: repoPath,
|
|
17975
|
+
encoding: "utf-8",
|
|
17976
|
+
stdio: "pipe",
|
|
17977
|
+
});
|
|
17978
|
+
return true;
|
|
17979
|
+
}
|
|
17980
|
+
catch {
|
|
17981
|
+
return false;
|
|
17982
|
+
}
|
|
17983
|
+
}
|
|
17984
|
+
|
|
17861
17985
|
const EXCLUDED_STATS_ATTRS = new Set(["human-instruction", "title"]);
|
|
17862
17986
|
const MAX_IMPORT_DEPTH = 10;
|
|
17863
17987
|
/**
|
|
@@ -18286,6 +18410,7 @@ function setupProgram() {
|
|
|
18286
18410
|
.option("--debug", "Enable debug logging")
|
|
18287
18411
|
.option("--verbose", "Enable verbose logging (alias for --debug)")
|
|
18288
18412
|
.option("--dry-run", "Preview input/output files without writing")
|
|
18413
|
+
.option("-y, --yes", "Skip confirmation prompts (for pre-actions)")
|
|
18289
18414
|
.action(async (options) => {
|
|
18290
18415
|
await handleExtractCommand(options);
|
|
18291
18416
|
});
|
|
@@ -18896,11 +19021,11 @@ async function handleExtractCommand(options) {
|
|
|
18896
19021
|
await validateRecipeFilesExist(options.recipe);
|
|
18897
19022
|
if (options.recipe.length === 1) {
|
|
18898
19023
|
// Single recipe - maintain backward compatibility
|
|
18899
|
-
await processRecipe(options.recipe[0], extractOptions, new ContentTracker(), debugLogger, options.baseDir, options.out, options.src);
|
|
19024
|
+
await processRecipe(options.recipe[0], extractOptions, new ContentTracker(), debugLogger, options.baseDir, options.out, options.src, options.yes);
|
|
18900
19025
|
}
|
|
18901
19026
|
else {
|
|
18902
19027
|
// Multiple recipes - process in order with auto-append
|
|
18903
|
-
await processMultipleRecipes(options.recipe, extractOptions, debugLogger, options.baseDir, options.out, options.src);
|
|
19028
|
+
await processMultipleRecipes(options.recipe, extractOptions, debugLogger, options.baseDir, options.out, options.src, options.yes);
|
|
18904
19029
|
}
|
|
18905
19030
|
}
|
|
18906
19031
|
else {
|
|
@@ -18926,13 +19051,13 @@ async function handleStatsCommand(options) {
|
|
|
18926
19051
|
/**
|
|
18927
19052
|
* Processes multiple recipe files in the specified order
|
|
18928
19053
|
*/
|
|
18929
|
-
async function processMultipleRecipes(recipePaths, baseOptions, debugLogger, cliBaseDir, cliOutFile, cliSrc) {
|
|
19054
|
+
async function processMultipleRecipes(recipePaths, baseOptions, debugLogger, cliBaseDir, cliOutFile, cliSrc, yesFlag) {
|
|
18930
19055
|
const contentTracker = new ContentTracker();
|
|
18931
19056
|
debugLogger.log(`Processing ${recipePaths.length} recipes in order`);
|
|
18932
19057
|
for (const recipePath of recipePaths) {
|
|
18933
19058
|
try {
|
|
18934
19059
|
debugLogger.log(`Starting processing of recipe: ${recipePath}`);
|
|
18935
|
-
await processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile, cliSrc);
|
|
19060
|
+
await processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile, cliSrc, yesFlag);
|
|
18936
19061
|
debugLogger.log(`Completed processing of recipe: ${recipePath}`);
|
|
18937
19062
|
}
|
|
18938
19063
|
catch (error) {
|
|
@@ -19041,10 +19166,106 @@ async function processFrontmatterInheritance(frontmatter, srcDir, types, languag
|
|
|
19041
19166
|
debugLogger?.log("Frontmatter after inheritance processing:", Object.keys(result));
|
|
19042
19167
|
return result;
|
|
19043
19168
|
}
|
|
19169
|
+
/**
|
|
19170
|
+
* Executes pre-actions defined in a recipe file
|
|
19171
|
+
*/
|
|
19172
|
+
async function executePreActions(preActions, yesFlag, debugLogger) {
|
|
19173
|
+
const pulledRepos = new Set();
|
|
19174
|
+
console.log("[Pre-Action] Executing pre-actions...");
|
|
19175
|
+
for (let i = 0; i < preActions.length; i++) {
|
|
19176
|
+
const action = preActions[i];
|
|
19177
|
+
if (action.type === "git-pull") {
|
|
19178
|
+
await handleGitPullAction(action, pulledRepos, yesFlag, debugLogger);
|
|
19179
|
+
}
|
|
19180
|
+
else {
|
|
19181
|
+
throw new Error(`Unknown pre-action type: ${action.type}`);
|
|
19182
|
+
}
|
|
19183
|
+
}
|
|
19184
|
+
console.log("[Pre-Action] All pre-actions completed successfully");
|
|
19185
|
+
}
|
|
19186
|
+
/**
|
|
19187
|
+
* Handles a git-pull pre-action
|
|
19188
|
+
*/
|
|
19189
|
+
async function handleGitPullAction(action, pulledRepos, yesFlag, debugLogger) {
|
|
19190
|
+
// Check if git-pull should be skipped via environment variable
|
|
19191
|
+
if (process.env.SKIP_GIT_PULL === "true" || process.env.SKIP_GIT_PULL === "1") {
|
|
19192
|
+
console.log(`[Pre-Action] Skipping git-pull (SKIP_GIT_PULL=${process.env.SKIP_GIT_PULL})`);
|
|
19193
|
+
debugLogger?.log(`Git-pull skipped due to SKIP_GIT_PULL environment variable`);
|
|
19194
|
+
return;
|
|
19195
|
+
}
|
|
19196
|
+
// Expand environment variables in path
|
|
19197
|
+
const expandedPath = resolvePath(action.path);
|
|
19198
|
+
const normalizedPath = path.normalize(path.resolve(expandedPath));
|
|
19199
|
+
console.log(`[Pre-Action] Executing git-pull for: ${normalizedPath}`);
|
|
19200
|
+
// Check for duplicate pull
|
|
19201
|
+
if (pulledRepos.has(normalizedPath)) {
|
|
19202
|
+
console.log(`[Pre-Action] Skipping git-pull for: ${normalizedPath} (already pulled)`);
|
|
19203
|
+
debugLogger?.log(`Skipping duplicate git-pull: ${normalizedPath}`);
|
|
19204
|
+
return;
|
|
19205
|
+
}
|
|
19206
|
+
// Confirmation prompt (unless -y flag is set)
|
|
19207
|
+
if (!yesFlag) {
|
|
19208
|
+
const confirmed = await promptConfirmation(normalizedPath, action.branch);
|
|
19209
|
+
if (!confirmed) {
|
|
19210
|
+
throw new Error("Pre-action cancelled by user");
|
|
19211
|
+
}
|
|
19212
|
+
}
|
|
19213
|
+
else {
|
|
19214
|
+
console.log(`[Pre-Action] Auto-confirmed (--yes flag)`);
|
|
19215
|
+
}
|
|
19216
|
+
// Execute git pull
|
|
19217
|
+
console.log("[Pre-Action] Pulling latest changes...");
|
|
19218
|
+
const result = await executeGitPull({
|
|
19219
|
+
path: normalizedPath,
|
|
19220
|
+
branch: action.branch,
|
|
19221
|
+
depth: action.depth,
|
|
19222
|
+
skipOnError: action["skip-on-error"] ?? false,
|
|
19223
|
+
}, debugLogger);
|
|
19224
|
+
if (result.success) {
|
|
19225
|
+
const statusMsg = result.updated
|
|
19226
|
+
? "✓ Git pull successful (changes pulled)"
|
|
19227
|
+
: "✓ Git pull successful (no changes)";
|
|
19228
|
+
console.log(`[Pre-Action] ${statusMsg}`);
|
|
19229
|
+
debugLogger?.log(`Git pull result: ${result.message}`);
|
|
19230
|
+
}
|
|
19231
|
+
else {
|
|
19232
|
+
const errorMsg = `✗ Error: ${result.message}`;
|
|
19233
|
+
console.error(`[Pre-Action] ${errorMsg}`);
|
|
19234
|
+
if (!action["skip-on-error"]) {
|
|
19235
|
+
throw new Error(`Pre-action failed: ${result.message}`);
|
|
19236
|
+
}
|
|
19237
|
+
else {
|
|
19238
|
+
console.warn("[Pre-Action] Continuing despite error (skip-on-error: true)");
|
|
19239
|
+
}
|
|
19240
|
+
}
|
|
19241
|
+
// Mark this repo as pulled
|
|
19242
|
+
pulledRepos.add(normalizedPath);
|
|
19243
|
+
}
|
|
19244
|
+
/**
|
|
19245
|
+
* Prompts the user for confirmation before executing git pull
|
|
19246
|
+
*/
|
|
19247
|
+
async function promptConfirmation(repoPath, branch) {
|
|
19248
|
+
console.log("[Pre-Action] Git pull confirmation required:");
|
|
19249
|
+
console.log(` Repository: ${repoPath}`);
|
|
19250
|
+
if (branch) {
|
|
19251
|
+
console.log(` Branch: ${branch}`);
|
|
19252
|
+
}
|
|
19253
|
+
console.log("");
|
|
19254
|
+
const rl = readline.createInterface({
|
|
19255
|
+
input: process.stdin,
|
|
19256
|
+
output: process.stdout,
|
|
19257
|
+
});
|
|
19258
|
+
return new Promise((resolve) => {
|
|
19259
|
+
rl.question("Continue? (y/N): ", (answer) => {
|
|
19260
|
+
rl.close();
|
|
19261
|
+
resolve(answer.toLowerCase() === "y");
|
|
19262
|
+
});
|
|
19263
|
+
});
|
|
19264
|
+
}
|
|
19044
19265
|
/**
|
|
19045
19266
|
* Processes a recipe file with multiple extract operations
|
|
19046
19267
|
*/
|
|
19047
|
-
async function processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile, cliSrc) {
|
|
19268
|
+
async function processRecipe(recipePath, baseOptions, contentTracker, debugLogger, cliBaseDir, cliOutFile, cliSrc, yesFlag) {
|
|
19048
19269
|
const resolvedPath = resolveRecipePath(recipePath);
|
|
19049
19270
|
debugLogger?.log(`Processing recipe at path: ${resolvedPath}`);
|
|
19050
19271
|
try {
|
|
@@ -19055,6 +19276,10 @@ async function processRecipe(recipePath, baseOptions, contentTracker, debugLogge
|
|
|
19055
19276
|
if (!Array.isArray(data?.recipe)) {
|
|
19056
19277
|
throw new Error("Invalid recipe file: 'recipe' array not found");
|
|
19057
19278
|
}
|
|
19279
|
+
// Execute pre-actions if defined
|
|
19280
|
+
if (data["pre-action"] && Array.isArray(data["pre-action"])) {
|
|
19281
|
+
await executePreActions(data["pre-action"], yesFlag || false, debugLogger);
|
|
19282
|
+
}
|
|
19058
19283
|
// Validate recipe structure and show warnings
|
|
19059
19284
|
debugLogger?.time("Recipe validation");
|
|
19060
19285
|
try {
|
|
@@ -17,6 +17,7 @@ export declare class RecipeValidator {
|
|
|
17
17
|
private getHelpfulMessageForProperty;
|
|
18
18
|
private isCommonMistake;
|
|
19
19
|
private checkCommonMistakes;
|
|
20
|
+
private validatePreActions;
|
|
20
21
|
}
|
|
21
22
|
export declare function getRecipeValidator(): Promise<RecipeValidator>;
|
|
22
23
|
//# sourceMappingURL=recipeValidator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recipeValidator.d.ts","sourceRoot":"","sources":["../src/recipeValidator.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAAM;;IAWd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG,gBAAgB;IA0CjD,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,4BAA4B;IAYpC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;
|
|
1
|
+
{"version":3,"file":"recipeValidator.d.ts","sourceRoot":"","sources":["../src/recipeValidator.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAAM;;IAWd,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB,cAAc,CAAC,UAAU,EAAE,GAAG,GAAG,gBAAgB;IA0CjD,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,4BAA4B;IAYpC,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;IAmD3B,OAAO,CAAC,kBAAkB;CA+B3B;AAKD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,eAAe,CAAC,CAMnE"}
|
package/dist/recipeValidator.js
CHANGED
|
@@ -131,6 +131,15 @@ export class RecipeValidator {
|
|
|
131
131
|
return commonMistakeProps.includes(property);
|
|
132
132
|
}
|
|
133
133
|
checkCommonMistakes(recipeData, result) {
|
|
134
|
+
// Validate pre-action if present
|
|
135
|
+
if (recipeData['pre-action']) {
|
|
136
|
+
if (!Array.isArray(recipeData['pre-action'])) {
|
|
137
|
+
result.warnings.push('Warning: Pre-action should be an array');
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.validatePreActions(recipeData['pre-action'], result);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
134
143
|
// Check for properties that should be under filters or frontmatter
|
|
135
144
|
if (Array.isArray(recipeData.recipe)) {
|
|
136
145
|
recipeData.recipe.forEach((item, index) => {
|
|
@@ -168,6 +177,33 @@ export class RecipeValidator {
|
|
|
168
177
|
}
|
|
169
178
|
});
|
|
170
179
|
}
|
|
180
|
+
validatePreActions(preActions, result) {
|
|
181
|
+
for (let i = 0; i < preActions.length; i++) {
|
|
182
|
+
const action = preActions[i];
|
|
183
|
+
if (!action || typeof action !== 'object') {
|
|
184
|
+
result.warnings.push(`Warning: Pre-action item ${i + 1} should be an object`);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (!action.type) {
|
|
188
|
+
result.warnings.push(`Warning: Pre-action item ${i + 1} is missing required 'type' field`);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (action.type === 'git-pull') {
|
|
192
|
+
if (!action.path) {
|
|
193
|
+
result.warnings.push(`Warning: Git-pull action ${i + 1} is missing required 'path' field`);
|
|
194
|
+
}
|
|
195
|
+
if (action.depth !== undefined && typeof action.depth !== 'number') {
|
|
196
|
+
result.warnings.push(`Warning: Git-pull action ${i + 1}: 'depth' should be a number`);
|
|
197
|
+
}
|
|
198
|
+
if (action.depth !== undefined && action.depth < 1) {
|
|
199
|
+
result.warnings.push(`Warning: Git-pull action ${i + 1}: 'depth' should be at least 1`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
result.warnings.push(`Warning: Pre-action item ${i + 1} has unknown type: ${action.type}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
171
207
|
}
|
|
172
208
|
// Singleton instance
|
|
173
209
|
let validatorInstance = null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface GitPullOptions {
|
|
2
|
+
path: string;
|
|
3
|
+
branch?: string;
|
|
4
|
+
depth?: number;
|
|
5
|
+
skipOnError?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface GitPullResult {
|
|
8
|
+
success: boolean;
|
|
9
|
+
message: string;
|
|
10
|
+
updated: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Executes git pull in the specified repository
|
|
14
|
+
* @param options - Configuration for the git pull operation
|
|
15
|
+
* @param debugLogger - Optional debug logger
|
|
16
|
+
* @returns Result of the git pull operation
|
|
17
|
+
*/
|
|
18
|
+
export declare function executeGitPull(options: GitPullOptions, debugLogger?: any): Promise<GitPullResult>;
|
|
19
|
+
/**
|
|
20
|
+
* Verifies that the given path is a git repository
|
|
21
|
+
* @param repoPath - Path to verify
|
|
22
|
+
* @returns True if the path is a git repository, false otherwise
|
|
23
|
+
*/
|
|
24
|
+
export declare function verifyGitRepository(repoPath: string): Promise<boolean>;
|
|
25
|
+
//# sourceMappingURL=gitActions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitActions.d.ts","sourceRoot":"","sources":["../../src/utils/gitActions.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,WAAW,CAAC,EAAE,GAAG,GAChB,OAAO,CAAC,aAAa,CAAC,CA2DxB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAkB5E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
/**
|
|
5
|
+
* Executes git pull in the specified repository
|
|
6
|
+
* @param options - Configuration for the git pull operation
|
|
7
|
+
* @param debugLogger - Optional debug logger
|
|
8
|
+
* @returns Result of the git pull operation
|
|
9
|
+
*/
|
|
10
|
+
export async function executeGitPull(options, debugLogger) {
|
|
11
|
+
try {
|
|
12
|
+
// Verify it's a git repository
|
|
13
|
+
const isRepo = await verifyGitRepository(options.path);
|
|
14
|
+
if (!isRepo) {
|
|
15
|
+
return {
|
|
16
|
+
success: false,
|
|
17
|
+
message: "Path is not a git repository",
|
|
18
|
+
updated: false,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// Switch to target branch if specified
|
|
22
|
+
if (options.branch) {
|
|
23
|
+
try {
|
|
24
|
+
debugLogger?.log(`Switching to branch: ${options.branch}`);
|
|
25
|
+
execSync(`git checkout ${options.branch}`, {
|
|
26
|
+
cwd: options.path,
|
|
27
|
+
encoding: "utf-8",
|
|
28
|
+
stdio: "pipe",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return {
|
|
33
|
+
success: false,
|
|
34
|
+
message: `Failed to checkout branch ${options.branch}: ${error.message}`,
|
|
35
|
+
updated: false,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Build git pull command
|
|
40
|
+
let command = "git pull";
|
|
41
|
+
if (options.depth) {
|
|
42
|
+
command += ` --depth=${options.depth}`;
|
|
43
|
+
}
|
|
44
|
+
debugLogger?.log(`Executing: ${command} in ${options.path}`);
|
|
45
|
+
// Execute git pull
|
|
46
|
+
const output = execSync(command, {
|
|
47
|
+
cwd: options.path,
|
|
48
|
+
encoding: "utf-8",
|
|
49
|
+
stdio: "pipe",
|
|
50
|
+
});
|
|
51
|
+
const updated = !output.includes("Already up to date");
|
|
52
|
+
return {
|
|
53
|
+
success: true,
|
|
54
|
+
message: output.trim(),
|
|
55
|
+
updated,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
message: error.message || "Unknown error",
|
|
62
|
+
updated: false,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Verifies that the given path is a git repository
|
|
68
|
+
* @param repoPath - Path to verify
|
|
69
|
+
* @returns True if the path is a git repository, false otherwise
|
|
70
|
+
*/
|
|
71
|
+
export async function verifyGitRepository(repoPath) {
|
|
72
|
+
try {
|
|
73
|
+
const gitDir = path.join(repoPath, ".git");
|
|
74
|
+
if (!fs.existsSync(gitDir)) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
// Verify with git command
|
|
78
|
+
execSync("git rev-parse --git-dir", {
|
|
79
|
+
cwd: repoPath,
|
|
80
|
+
encoding: "utf-8",
|
|
81
|
+
stdio: "pipe",
|
|
82
|
+
});
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aramassa/ai-rules",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "This repository collects guidelines and instructions for developing AI agents. It contains documents covering communication rules, coding standards, testing strategies, and general operational practices.",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"packages/extract",
|
|
@@ -14,6 +14,53 @@
|
|
|
14
14
|
},
|
|
15
15
|
"additionalProperties": false
|
|
16
16
|
},
|
|
17
|
+
"pre-action": {
|
|
18
|
+
"type": "array",
|
|
19
|
+
"description": "Actions to execute before processing recipe items",
|
|
20
|
+
"items": {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"type": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"enum": ["git-pull"],
|
|
26
|
+
"description": "Type of pre-action to execute"
|
|
27
|
+
},
|
|
28
|
+
"path": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"description": "Path to the git repository (for git-pull action)"
|
|
31
|
+
},
|
|
32
|
+
"branch": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"description": "Specific branch to pull (optional)"
|
|
35
|
+
},
|
|
36
|
+
"depth": {
|
|
37
|
+
"type": "number",
|
|
38
|
+
"minimum": 1,
|
|
39
|
+
"description": "Shallow clone depth (optional)"
|
|
40
|
+
},
|
|
41
|
+
"skip-on-error": {
|
|
42
|
+
"type": "boolean",
|
|
43
|
+
"description": "Whether to continue on error (default: false)"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"required": ["type"],
|
|
47
|
+
"allOf": [
|
|
48
|
+
{
|
|
49
|
+
"if": {
|
|
50
|
+
"properties": {
|
|
51
|
+
"type": {
|
|
52
|
+
"const": "git-pull"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"then": {
|
|
57
|
+
"required": ["path"]
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"additionalProperties": false
|
|
62
|
+
}
|
|
63
|
+
},
|
|
17
64
|
"recipe": {
|
|
18
65
|
"type": "array",
|
|
19
66
|
"description": "Array of recipe items",
|