@mindfoldhq/trellis 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/LICENSE +110 -0
- package/README.md +149 -0
- package/bin/trellis.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +42 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +236 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/configurators/claude.d.ts +35 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +83 -0
- package/dist/configurators/claude.js.map +1 -0
- package/dist/configurators/cursor.d.ts +8 -0
- package/dist/configurators/cursor.d.ts.map +1 -0
- package/dist/configurators/cursor.js +22 -0
- package/dist/configurators/cursor.js.map +1 -0
- package/dist/configurators/templates.d.ts +40 -0
- package/dist/configurators/templates.d.ts.map +1 -0
- package/dist/configurators/templates.js +67 -0
- package/dist/configurators/templates.js.map +1 -0
- package/dist/configurators/workflow.d.ts +16 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +169 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/constants/paths.d.ts +69 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +80 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/agents/check.txt +120 -0
- package/dist/templates/agents/debug.txt +121 -0
- package/dist/templates/agents/dispatch.txt +201 -0
- package/dist/templates/agents/implement.txt +114 -0
- package/dist/templates/agents/index.d.ts +35 -0
- package/dist/templates/agents/index.d.ts.map +1 -0
- package/dist/templates/agents/index.js +71 -0
- package/dist/templates/agents/index.js.map +1 -0
- package/dist/templates/agents/research.txt +258 -0
- package/dist/templates/commands/claude/start.md.txt +127 -0
- package/dist/templates/commands/common/before-backend-dev.txt +13 -0
- package/dist/templates/commands/common/before-frontend-dev.txt +13 -0
- package/dist/templates/commands/common/break-loop.txt +107 -0
- package/dist/templates/commands/common/check-backend.txt +13 -0
- package/dist/templates/commands/common/check-cross-layer.txt +153 -0
- package/dist/templates/commands/common/check-frontend.txt +13 -0
- package/dist/templates/commands/common/create-command.txt +154 -0
- package/dist/templates/commands/common/finish-work.txt +129 -0
- package/dist/templates/commands/common/integrate-skill.txt +219 -0
- package/dist/templates/commands/common/onboard-developer.txt +355 -0
- package/dist/templates/commands/common/record-agent-flow.txt +62 -0
- package/dist/templates/commands/cursor/start.md.txt +94 -0
- package/dist/templates/commands/index.d.ts +46 -0
- package/dist/templates/commands/index.d.ts.map +1 -0
- package/dist/templates/commands/index.js +151 -0
- package/dist/templates/commands/index.js.map +1 -0
- package/dist/templates/extract.d.ts +22 -0
- package/dist/templates/extract.d.ts.map +1 -0
- package/dist/templates/extract.js +34 -0
- package/dist/templates/extract.js.map +1 -0
- package/dist/templates/hooks/index.d.ts +33 -0
- package/dist/templates/hooks/index.d.ts.map +1 -0
- package/dist/templates/hooks/index.js +53 -0
- package/dist/templates/hooks/index.js.map +1 -0
- package/dist/templates/hooks/inject-subagent-context.py +620 -0
- package/dist/templates/hooks/settings.json +16 -0
- package/dist/templates/markdown/agent-traces-index.md.txt +124 -0
- package/dist/templates/markdown/agents.md.txt +18 -0
- package/dist/templates/markdown/gitignore.txt +3 -0
- package/dist/templates/markdown/index.d.ts +26 -0
- package/dist/templates/markdown/index.d.ts.map +1 -0
- package/dist/templates/markdown/index.js +33 -0
- package/dist/templates/markdown/index.js.map +1 -0
- package/dist/templates/markdown/init-agent.md.txt +315 -0
- package/dist/templates/markdown/structure/backend/database-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/backend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/structure/backend/error-handling.md.txt +51 -0
- package/dist/templates/markdown/structure/backend/index.md.txt +38 -0
- package/dist/templates/markdown/structure/backend/logging-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/backend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/component-guidelines.md.txt +59 -0
- package/dist/templates/markdown/structure/frontend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/structure/frontend/hook-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/index.md.txt +39 -0
- package/dist/templates/markdown/structure/frontend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/state-management.md.txt +51 -0
- package/dist/templates/markdown/structure/frontend/type-safety.md.txt +51 -0
- package/dist/templates/markdown/structure/guides/code-reuse-thinking-guide.md.txt +92 -0
- package/dist/templates/markdown/structure/guides/cross-layer-thinking-guide.md.txt +94 -0
- package/dist/templates/markdown/structure/guides/index.md.txt +79 -0
- package/dist/templates/markdown/workflow.md.txt +335 -0
- package/dist/templates/scripts/add-session.sh.txt +384 -0
- package/dist/templates/scripts/common/developer.sh.txt +130 -0
- package/dist/templates/scripts/common/git-context.sh.txt +237 -0
- package/dist/templates/scripts/common/paths.sh.txt +201 -0
- package/dist/templates/scripts/create-bootstrap.sh.txt +298 -0
- package/dist/templates/scripts/feature.sh.txt +700 -0
- package/dist/templates/scripts/get-context.sh.txt +7 -0
- package/dist/templates/scripts/get-developer.sh.txt +15 -0
- package/dist/templates/scripts/index.d.ts +25 -0
- package/dist/templates/scripts/index.d.ts.map +1 -0
- package/dist/templates/scripts/index.js +28 -0
- package/dist/templates/scripts/index.js.map +1 -0
- package/dist/templates/scripts/init-developer.sh.txt +34 -0
- package/dist/types/ai-tools.d.ts +35 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +31 -0
- package/dist/types/ai-tools.js.map +1 -0
- package/dist/utils/file-writer.d.ts +23 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +140 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/project-detector.d.ts +16 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +186 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Get current developer name
|
|
3
|
+
#
|
|
4
|
+
# This is a wrapper that uses common/paths.sh
|
|
5
|
+
|
|
6
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
|
+
source "$SCRIPT_DIR/common/paths.sh"
|
|
8
|
+
|
|
9
|
+
developer=$(get_developer)
|
|
10
|
+
if [[ -n "$developer" ]]; then
|
|
11
|
+
echo "$developer"
|
|
12
|
+
else
|
|
13
|
+
echo "Developer not initialized" >&2
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script templates for Trellis workflow
|
|
3
|
+
*
|
|
4
|
+
* Directory structure:
|
|
5
|
+
* scripts/
|
|
6
|
+
* ├── common/ # Shared utilities (to be sourced)
|
|
7
|
+
* │ ├── paths.sh.txt # Path utilities
|
|
8
|
+
* │ ├── developer.sh.txt # Developer management
|
|
9
|
+
* │ └── git-context.sh.txt # Git context (main implementation)
|
|
10
|
+
* ├── feature.sh.txt # Feature management
|
|
11
|
+
* ├── get-context.sh.txt # Wrapper for git-context.sh
|
|
12
|
+
* ├── get-developer.sh.txt # Get developer name
|
|
13
|
+
* ├── init-developer.sh.txt
|
|
14
|
+
* └── add-session.sh.txt # Add session and update index
|
|
15
|
+
*/
|
|
16
|
+
export declare const commonPathsScript: string;
|
|
17
|
+
export declare const commonDeveloperScript: string;
|
|
18
|
+
export declare const commonGitContextScript: string;
|
|
19
|
+
export declare const initDeveloperScript: string;
|
|
20
|
+
export declare const getDeveloperScript: string;
|
|
21
|
+
export declare const featureScript: string;
|
|
22
|
+
export declare const getContextScript: string;
|
|
23
|
+
export declare const addSessionScript: string;
|
|
24
|
+
export declare const createBootstrapScript: string;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/scripts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,eAAO,MAAM,iBAAiB,EAAE,MAA0C,CAAC;AAC3E,eAAO,MAAM,qBAAqB,EAAE,MAEnC,CAAC;AACF,eAAO,MAAM,sBAAsB,EAAE,MAEpC,CAAC;AAGF,eAAO,MAAM,mBAAmB,EAAE,MAA4C,CAAC;AAC/E,eAAO,MAAM,kBAAkB,EAAE,MAA2C,CAAC;AAC7E,eAAO,MAAM,aAAa,EAAE,MAAqC,CAAC;AAClE,eAAO,MAAM,gBAAgB,EAAE,MAAyC,CAAC;AACzE,eAAO,MAAM,gBAAgB,EAAE,MAAyC,CAAC;AACzE,eAAO,MAAM,qBAAqB,EAAE,MAEnC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script templates for Trellis workflow
|
|
3
|
+
*
|
|
4
|
+
* Directory structure:
|
|
5
|
+
* scripts/
|
|
6
|
+
* ├── common/ # Shared utilities (to be sourced)
|
|
7
|
+
* │ ├── paths.sh.txt # Path utilities
|
|
8
|
+
* │ ├── developer.sh.txt # Developer management
|
|
9
|
+
* │ └── git-context.sh.txt # Git context (main implementation)
|
|
10
|
+
* ├── feature.sh.txt # Feature management
|
|
11
|
+
* ├── get-context.sh.txt # Wrapper for git-context.sh
|
|
12
|
+
* ├── get-developer.sh.txt # Get developer name
|
|
13
|
+
* ├── init-developer.sh.txt
|
|
14
|
+
* └── add-session.sh.txt # Add session and update index
|
|
15
|
+
*/
|
|
16
|
+
import { readScript } from "../extract.js";
|
|
17
|
+
// Common utilities (to be sourced by other scripts)
|
|
18
|
+
export const commonPathsScript = readScript("common/paths.sh.txt");
|
|
19
|
+
export const commonDeveloperScript = readScript("common/developer.sh.txt");
|
|
20
|
+
export const commonGitContextScript = readScript("common/git-context.sh.txt");
|
|
21
|
+
// Main scripts
|
|
22
|
+
export const initDeveloperScript = readScript("init-developer.sh.txt");
|
|
23
|
+
export const getDeveloperScript = readScript("get-developer.sh.txt");
|
|
24
|
+
export const featureScript = readScript("feature.sh.txt");
|
|
25
|
+
export const getContextScript = readScript("get-context.sh.txt");
|
|
26
|
+
export const addSessionScript = readScript("add-session.sh.txt");
|
|
27
|
+
export const createBootstrapScript = readScript("create-bootstrap.sh.txt");
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/scripts/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,oDAAoD;AACpD,MAAM,CAAC,MAAM,iBAAiB,GAAW,UAAU,CAAC,qBAAqB,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,qBAAqB,GAAW,UAAU,CACrD,yBAAyB,CAC1B,CAAC;AACF,MAAM,CAAC,MAAM,sBAAsB,GAAW,UAAU,CACtD,2BAA2B,CAC5B,CAAC;AAEF,eAAe;AACf,MAAM,CAAC,MAAM,mBAAmB,GAAW,UAAU,CAAC,uBAAuB,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAW,UAAU,CAAC,sBAAsB,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,aAAa,GAAW,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAClE,MAAM,CAAC,MAAM,gBAAgB,GAAW,UAAU,CAAC,oBAAoB,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,gBAAgB,GAAW,UAAU,CAAC,oBAAoB,CAAC,CAAC;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAW,UAAU,CACrD,yBAAyB,CAC1B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Initialize developer for workflow
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# ./.trellis/scripts/init-developer.sh <developer-name>
|
|
6
|
+
#
|
|
7
|
+
# This creates:
|
|
8
|
+
# - .trellis/.developer file with developer info
|
|
9
|
+
# - .trellis/agent-traces/<name>/ directory structure
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
source "$SCRIPT_DIR/common/paths.sh"
|
|
15
|
+
source "$SCRIPT_DIR/common/developer.sh"
|
|
16
|
+
|
|
17
|
+
if [[ -z "$1" ]]; then
|
|
18
|
+
echo "Usage: $0 <developer-name>"
|
|
19
|
+
echo ""
|
|
20
|
+
echo "Example:"
|
|
21
|
+
echo " $0 john"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Check if already initialized
|
|
26
|
+
existing=$(get_developer)
|
|
27
|
+
if [[ -n "$existing" ]]; then
|
|
28
|
+
echo "Developer already initialized: $existing"
|
|
29
|
+
echo ""
|
|
30
|
+
echo "To reinitialize, remove $DIR_WORKFLOW/$FILE_DEVELOPER first"
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
init_developer "$1"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Tool Types and Registry
|
|
3
|
+
*
|
|
4
|
+
* Defines supported AI coding tools and which command templates they can use.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Supported AI coding tools
|
|
8
|
+
*/
|
|
9
|
+
export type AITool = "claude-code" | "cursor";
|
|
10
|
+
/**
|
|
11
|
+
* Template directory categories
|
|
12
|
+
*/
|
|
13
|
+
export type TemplateDir = "common" | "claude" | "cursor";
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for an AI tool
|
|
16
|
+
*/
|
|
17
|
+
export interface AIToolConfig {
|
|
18
|
+
/** Display name of the tool */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Command template directory names to include */
|
|
21
|
+
templateDirs: TemplateDir[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Registry of all supported AI tools and their configurations
|
|
25
|
+
*/
|
|
26
|
+
export declare const AI_TOOLS: Record<AITool, AIToolConfig>;
|
|
27
|
+
/**
|
|
28
|
+
* Get the configuration for a specific AI tool
|
|
29
|
+
*/
|
|
30
|
+
export declare function getToolConfig(tool: AITool): AIToolConfig;
|
|
31
|
+
/**
|
|
32
|
+
* Get template directories for a specific tool
|
|
33
|
+
*/
|
|
34
|
+
export declare function getTemplateDirs(tool: AITool): TemplateDir[];
|
|
35
|
+
//# sourceMappingURL=ai-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tools.d.ts","sourceRoot":"","sources":["../../src/types/ai-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,YAAY,EAAE,WAAW,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CASjD,CAAC;AAEF;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAExD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAE3D"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Tool Types and Registry
|
|
3
|
+
*
|
|
4
|
+
* Defines supported AI coding tools and which command templates they can use.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Registry of all supported AI tools and their configurations
|
|
8
|
+
*/
|
|
9
|
+
export const AI_TOOLS = {
|
|
10
|
+
"claude-code": {
|
|
11
|
+
name: "Claude Code",
|
|
12
|
+
templateDirs: ["common", "claude"],
|
|
13
|
+
},
|
|
14
|
+
cursor: {
|
|
15
|
+
name: "Cursor",
|
|
16
|
+
templateDirs: ["common", "cursor"],
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Get the configuration for a specific AI tool
|
|
21
|
+
*/
|
|
22
|
+
export function getToolConfig(tool) {
|
|
23
|
+
return AI_TOOLS[tool];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get template directories for a specific tool
|
|
27
|
+
*/
|
|
28
|
+
export function getTemplateDirs(tool) {
|
|
29
|
+
return AI_TOOLS[tool].templateDirs;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=ai-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tools.js","sourceRoot":"","sources":["../../src/types/ai-tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsBH;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAiC;IACpD,aAAa,EAAE;QACb,IAAI,EAAE,aAAa;QACnB,YAAY,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;KACnC;IACD,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;KACnC;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type WriteMode = "ask" | "force" | "skip" | "append";
|
|
2
|
+
export interface WriteOptions {
|
|
3
|
+
mode: WriteMode;
|
|
4
|
+
}
|
|
5
|
+
export declare function setWriteMode(mode: WriteMode): void;
|
|
6
|
+
export declare function getWriteMode(): WriteMode;
|
|
7
|
+
/**
|
|
8
|
+
* Write file with conflict handling
|
|
9
|
+
* - If file doesn't exist: write directly
|
|
10
|
+
* - If file exists and content is identical: skip silently
|
|
11
|
+
* - If file exists and mode is 'force': overwrite
|
|
12
|
+
* - If file exists and mode is 'skip': skip
|
|
13
|
+
* - If file exists and mode is 'append': append to end
|
|
14
|
+
* - If file exists and mode is 'ask': prompt user
|
|
15
|
+
*/
|
|
16
|
+
export declare function writeFile(filePath: string, content: string, options?: {
|
|
17
|
+
executable?: boolean;
|
|
18
|
+
}): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Ensure directory exists
|
|
21
|
+
*/
|
|
22
|
+
export declare function ensureDir(dirPath: string): void;
|
|
23
|
+
//# sourceMappingURL=file-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-writer.d.ts","sourceRoot":"","sources":["../../src/utils/file-writer.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;CACjB;AASD,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAElD;AAED,wBAAgB,YAAY,IAAI,SAAS,CAExC;AA6BD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,OAAO,CAAC,CAwGlB;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import inquirer from "inquirer";
|
|
5
|
+
// Global write mode (set from CLI options)
|
|
6
|
+
let globalWriteMode = "ask";
|
|
7
|
+
export function setWriteMode(mode) {
|
|
8
|
+
globalWriteMode = mode;
|
|
9
|
+
}
|
|
10
|
+
export function getWriteMode() {
|
|
11
|
+
return globalWriteMode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get relative path from cwd for display
|
|
15
|
+
*/
|
|
16
|
+
function getRelativePath(filePath) {
|
|
17
|
+
const cwd = process.cwd();
|
|
18
|
+
const relativePath = path.relative(cwd, filePath);
|
|
19
|
+
return relativePath || path.basename(filePath);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Append content to file
|
|
23
|
+
*/
|
|
24
|
+
function appendToFile(filePath, content, options) {
|
|
25
|
+
const existingContent = fs.readFileSync(filePath, "utf-8");
|
|
26
|
+
const newContent = existingContent.endsWith("\n")
|
|
27
|
+
? existingContent + content
|
|
28
|
+
: existingContent + "\n" + content;
|
|
29
|
+
fs.writeFileSync(filePath, newContent);
|
|
30
|
+
if (options?.executable) {
|
|
31
|
+
fs.chmodSync(filePath, "755");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write file with conflict handling
|
|
36
|
+
* - If file doesn't exist: write directly
|
|
37
|
+
* - If file exists and content is identical: skip silently
|
|
38
|
+
* - If file exists and mode is 'force': overwrite
|
|
39
|
+
* - If file exists and mode is 'skip': skip
|
|
40
|
+
* - If file exists and mode is 'append': append to end
|
|
41
|
+
* - If file exists and mode is 'ask': prompt user
|
|
42
|
+
*/
|
|
43
|
+
export async function writeFile(filePath, content, options) {
|
|
44
|
+
const exists = fs.existsSync(filePath);
|
|
45
|
+
const displayPath = getRelativePath(filePath);
|
|
46
|
+
if (!exists) {
|
|
47
|
+
// File doesn't exist, write directly
|
|
48
|
+
fs.writeFileSync(filePath, content);
|
|
49
|
+
if (options?.executable) {
|
|
50
|
+
fs.chmodSync(filePath, "755");
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
// File exists, check if content is identical
|
|
55
|
+
const existingContent = fs.readFileSync(filePath, "utf-8");
|
|
56
|
+
if (existingContent === content) {
|
|
57
|
+
// Content identical, skip silently (no output)
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
// File exists with different content, handle based on mode
|
|
61
|
+
const mode = globalWriteMode;
|
|
62
|
+
if (mode === "force") {
|
|
63
|
+
fs.writeFileSync(filePath, content);
|
|
64
|
+
if (options?.executable) {
|
|
65
|
+
fs.chmodSync(filePath, "755");
|
|
66
|
+
}
|
|
67
|
+
console.log(chalk.yellow(` ↻ Overwritten: ${displayPath}`));
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
if (mode === "skip") {
|
|
71
|
+
console.log(chalk.gray(` ○ Skipped: ${displayPath} (already exists)`));
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
if (mode === "append") {
|
|
75
|
+
appendToFile(filePath, content, options);
|
|
76
|
+
console.log(chalk.blue(` + Appended: ${displayPath}`));
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
// mode === 'ask': Interactive prompt
|
|
80
|
+
const { action } = await inquirer.prompt([
|
|
81
|
+
{
|
|
82
|
+
type: "list",
|
|
83
|
+
name: "action",
|
|
84
|
+
message: `File "${displayPath}" already exists. What would you like to do?`,
|
|
85
|
+
choices: [
|
|
86
|
+
{ name: "Skip (keep existing)", value: "skip" },
|
|
87
|
+
{ name: "Overwrite", value: "overwrite" },
|
|
88
|
+
{ name: "Append to end", value: "append" },
|
|
89
|
+
{ name: "Skip all remaining conflicts", value: "skip-all" },
|
|
90
|
+
{ name: "Overwrite all remaining conflicts", value: "overwrite-all" },
|
|
91
|
+
{ name: "Append all remaining conflicts", value: "append-all" },
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
]);
|
|
95
|
+
if (action === "skip") {
|
|
96
|
+
console.log(chalk.gray(` ○ Skipped: ${displayPath}`));
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
if (action === "overwrite") {
|
|
100
|
+
fs.writeFileSync(filePath, content);
|
|
101
|
+
if (options?.executable) {
|
|
102
|
+
fs.chmodSync(filePath, "755");
|
|
103
|
+
}
|
|
104
|
+
console.log(chalk.yellow(` ↻ Overwritten: ${displayPath}`));
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if (action === "append") {
|
|
108
|
+
appendToFile(filePath, content, options);
|
|
109
|
+
console.log(chalk.blue(` + Appended: ${displayPath}`));
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
if (action === "skip-all") {
|
|
113
|
+
globalWriteMode = "skip";
|
|
114
|
+
console.log(chalk.gray(` ○ Skipped: ${displayPath}`));
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (action === "overwrite-all") {
|
|
118
|
+
globalWriteMode = "force";
|
|
119
|
+
fs.writeFileSync(filePath, content);
|
|
120
|
+
if (options?.executable) {
|
|
121
|
+
fs.chmodSync(filePath, "755");
|
|
122
|
+
}
|
|
123
|
+
console.log(chalk.yellow(` ↻ Overwritten: ${displayPath}`));
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
if (action === "append-all") {
|
|
127
|
+
globalWriteMode = "append";
|
|
128
|
+
appendToFile(filePath, content, options);
|
|
129
|
+
console.log(chalk.blue(` + Appended: ${displayPath}`));
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Ensure directory exists
|
|
136
|
+
*/
|
|
137
|
+
export function ensureDir(dirPath) {
|
|
138
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=file-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-writer.js","sourceRoot":"","sources":["../../src/utils/file-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project type detected by analyzing project files
|
|
3
|
+
*/
|
|
4
|
+
export type ProjectType = "frontend" | "backend" | "fullstack" | "unknown";
|
|
5
|
+
/**
|
|
6
|
+
* Detect project type by analyzing project files
|
|
7
|
+
*
|
|
8
|
+
* @param cwd - Current working directory to analyze
|
|
9
|
+
* @returns Detected project type
|
|
10
|
+
*/
|
|
11
|
+
export declare function detectProjectType(cwd: string): ProjectType;
|
|
12
|
+
/**
|
|
13
|
+
* Get human-readable description of project type
|
|
14
|
+
*/
|
|
15
|
+
export declare function getProjectTypeDescription(type: ProjectType): string;
|
|
16
|
+
//# sourceMappingURL=project-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-detector.d.ts","sourceRoot":"","sources":["../../src/utils/project-detector.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAiK3E;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAqB1D;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAWnE"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Files that indicate a frontend project
|
|
5
|
+
*/
|
|
6
|
+
const FRONTEND_INDICATORS = [
|
|
7
|
+
// Package managers with frontend deps
|
|
8
|
+
"package.json", // Will check for frontend dependencies
|
|
9
|
+
// Build tools
|
|
10
|
+
"vite.config.ts",
|
|
11
|
+
"vite.config.js",
|
|
12
|
+
"next.config.js",
|
|
13
|
+
"next.config.ts",
|
|
14
|
+
"next.config.mjs",
|
|
15
|
+
"nuxt.config.ts",
|
|
16
|
+
"nuxt.config.js",
|
|
17
|
+
"webpack.config.js",
|
|
18
|
+
"rollup.config.js",
|
|
19
|
+
// Framework configs
|
|
20
|
+
"svelte.config.js",
|
|
21
|
+
"astro.config.mjs",
|
|
22
|
+
"angular.json",
|
|
23
|
+
"vue.config.js",
|
|
24
|
+
// Source directories
|
|
25
|
+
"src/App.tsx",
|
|
26
|
+
"src/App.jsx",
|
|
27
|
+
"src/App.vue",
|
|
28
|
+
"src/app/page.tsx",
|
|
29
|
+
"app/page.tsx",
|
|
30
|
+
"pages/index.tsx",
|
|
31
|
+
"pages/index.jsx",
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Files that indicate a backend project
|
|
35
|
+
*/
|
|
36
|
+
const BACKEND_INDICATORS = [
|
|
37
|
+
// Go
|
|
38
|
+
"go.mod",
|
|
39
|
+
"go.sum",
|
|
40
|
+
// Rust
|
|
41
|
+
"Cargo.toml",
|
|
42
|
+
"Cargo.lock",
|
|
43
|
+
// Python
|
|
44
|
+
"requirements.txt",
|
|
45
|
+
"pyproject.toml",
|
|
46
|
+
"setup.py",
|
|
47
|
+
"Pipfile",
|
|
48
|
+
"poetry.lock",
|
|
49
|
+
// Java/Kotlin
|
|
50
|
+
"pom.xml",
|
|
51
|
+
"build.gradle",
|
|
52
|
+
"build.gradle.kts",
|
|
53
|
+
// Ruby
|
|
54
|
+
"Gemfile",
|
|
55
|
+
// PHP
|
|
56
|
+
"composer.json",
|
|
57
|
+
// .NET
|
|
58
|
+
"*.csproj",
|
|
59
|
+
"*.fsproj",
|
|
60
|
+
// Elixir
|
|
61
|
+
"mix.exs",
|
|
62
|
+
// Node.js backend indicators
|
|
63
|
+
"server.ts",
|
|
64
|
+
"server.js",
|
|
65
|
+
"src/server.ts",
|
|
66
|
+
"src/index.ts", // Could be backend entry
|
|
67
|
+
];
|
|
68
|
+
/**
|
|
69
|
+
* Frontend dependencies in package.json
|
|
70
|
+
*/
|
|
71
|
+
const FRONTEND_DEPS = [
|
|
72
|
+
"react",
|
|
73
|
+
"vue",
|
|
74
|
+
"svelte",
|
|
75
|
+
"angular",
|
|
76
|
+
"@angular/core",
|
|
77
|
+
"next",
|
|
78
|
+
"nuxt",
|
|
79
|
+
"astro",
|
|
80
|
+
"solid-js",
|
|
81
|
+
"preact",
|
|
82
|
+
"lit",
|
|
83
|
+
"@remix-run/react",
|
|
84
|
+
];
|
|
85
|
+
/**
|
|
86
|
+
* Backend dependencies in package.json
|
|
87
|
+
*/
|
|
88
|
+
const BACKEND_DEPS = [
|
|
89
|
+
"express",
|
|
90
|
+
"fastify",
|
|
91
|
+
"hono",
|
|
92
|
+
"koa",
|
|
93
|
+
"hapi",
|
|
94
|
+
"nest",
|
|
95
|
+
"@nestjs/core",
|
|
96
|
+
"fastapi",
|
|
97
|
+
"flask",
|
|
98
|
+
"django",
|
|
99
|
+
];
|
|
100
|
+
/**
|
|
101
|
+
* Check if a file exists in the project directory
|
|
102
|
+
*/
|
|
103
|
+
function fileExists(cwd, filename) {
|
|
104
|
+
// Handle glob patterns like *.csproj
|
|
105
|
+
if (filename.includes("*")) {
|
|
106
|
+
const dir = path.dirname(filename) || ".";
|
|
107
|
+
const pattern = path.basename(filename);
|
|
108
|
+
const searchDir = path.join(cwd, dir);
|
|
109
|
+
if (!fs.existsSync(searchDir))
|
|
110
|
+
return false;
|
|
111
|
+
try {
|
|
112
|
+
const files = fs.readdirSync(searchDir);
|
|
113
|
+
const regex = new RegExp("^" + pattern.replace(/\*/g, ".*").replace(/\./g, "\\.") + "$");
|
|
114
|
+
return files.some((f) => regex.test(f));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return fs.existsSync(path.join(cwd, filename));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Check package.json for frontend/backend dependencies
|
|
124
|
+
*/
|
|
125
|
+
function checkPackageJson(cwd) {
|
|
126
|
+
const packageJsonPath = path.join(cwd, "package.json");
|
|
127
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
128
|
+
return { hasFrontend: false, hasBackend: false };
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const content = fs.readFileSync(packageJsonPath, "utf-8");
|
|
132
|
+
const pkg = JSON.parse(content);
|
|
133
|
+
const allDeps = {
|
|
134
|
+
...pkg.dependencies,
|
|
135
|
+
...pkg.devDependencies,
|
|
136
|
+
};
|
|
137
|
+
const depNames = Object.keys(allDeps ?? {});
|
|
138
|
+
const hasFrontend = FRONTEND_DEPS.some((dep) => depNames.includes(dep));
|
|
139
|
+
const hasBackend = BACKEND_DEPS.some((dep) => depNames.includes(dep));
|
|
140
|
+
return { hasFrontend, hasBackend };
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return { hasFrontend: false, hasBackend: false };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Detect project type by analyzing project files
|
|
148
|
+
*
|
|
149
|
+
* @param cwd - Current working directory to analyze
|
|
150
|
+
* @returns Detected project type
|
|
151
|
+
*/
|
|
152
|
+
export function detectProjectType(cwd) {
|
|
153
|
+
// Check for file indicators
|
|
154
|
+
const hasFrontendFiles = FRONTEND_INDICATORS.some((f) => fileExists(cwd, f));
|
|
155
|
+
const hasBackendFiles = BACKEND_INDICATORS.some((f) => fileExists(cwd, f));
|
|
156
|
+
// Check package.json dependencies
|
|
157
|
+
const { hasFrontend: hasFrontendDeps, hasBackend: hasBackendDeps } = checkPackageJson(cwd);
|
|
158
|
+
const isFrontend = hasFrontendFiles || hasFrontendDeps;
|
|
159
|
+
const isBackend = hasBackendFiles || hasBackendDeps;
|
|
160
|
+
if (isFrontend && isBackend) {
|
|
161
|
+
return "fullstack";
|
|
162
|
+
}
|
|
163
|
+
else if (isFrontend) {
|
|
164
|
+
return "frontend";
|
|
165
|
+
}
|
|
166
|
+
else if (isBackend) {
|
|
167
|
+
return "backend";
|
|
168
|
+
}
|
|
169
|
+
return "unknown";
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get human-readable description of project type
|
|
173
|
+
*/
|
|
174
|
+
export function getProjectTypeDescription(type) {
|
|
175
|
+
switch (type) {
|
|
176
|
+
case "frontend":
|
|
177
|
+
return "Frontend project (UI/client-side)";
|
|
178
|
+
case "backend":
|
|
179
|
+
return "Backend project (server-side/API)";
|
|
180
|
+
case "fullstack":
|
|
181
|
+
return "Fullstack project (frontend + backend)";
|
|
182
|
+
case "unknown":
|
|
183
|
+
return "Unknown project type (defaults to fullstack)";
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=project-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-detector.js","sourceRoot":"","sources":["../../src/utils/project-detector.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mindfoldhq/trellis",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI capabilities grow like ivy — Trellis provides the structure to guide them along a disciplined path",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"trellis": "./bin/trellis.js",
|
|
10
|
+
"tl": "./bin/trellis.js"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ai",
|
|
17
|
+
"workflow",
|
|
18
|
+
"cursor",
|
|
19
|
+
"claude",
|
|
20
|
+
"cli",
|
|
21
|
+
"developer-tools",
|
|
22
|
+
"agent",
|
|
23
|
+
"memory",
|
|
24
|
+
"trellis"
|
|
25
|
+
],
|
|
26
|
+
"author": "Mindfold LLC",
|
|
27
|
+
"license": "FSL-1.1-MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"chalk": "^5.3.0",
|
|
30
|
+
"commander": "^12.1.0",
|
|
31
|
+
"figlet": "^1.9.4",
|
|
32
|
+
"inquirer": "^9.3.7"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@eslint/js": "^9.18.0",
|
|
36
|
+
"@types/figlet": "^1.7.0",
|
|
37
|
+
"@types/inquirer": "^9.0.7",
|
|
38
|
+
"@types/node": "^20.17.10",
|
|
39
|
+
"eslint": "^9.18.0",
|
|
40
|
+
"prettier": "^3.4.2",
|
|
41
|
+
"typescript": "^5.7.2",
|
|
42
|
+
"typescript-eslint": "^8.21.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"bin",
|
|
50
|
+
"README.md",
|
|
51
|
+
"LICENSE.md"
|
|
52
|
+
],
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://github.com/mindfold-ai/trellis.git"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsc && pnpm run copy-templates",
|
|
59
|
+
"copy-templates": "node scripts/copy-templates.js",
|
|
60
|
+
"dev": "tsc --watch",
|
|
61
|
+
"start": "node ./dist/cli/index.js",
|
|
62
|
+
"lint": "eslint src/",
|
|
63
|
+
"lint:fix": "eslint src/ --fix",
|
|
64
|
+
"format": "prettier --write src/",
|
|
65
|
+
"format:check": "prettier --check src/",
|
|
66
|
+
"typecheck": "tsc --noEmit",
|
|
67
|
+
"release": "git add -A && git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates' && pnpm version patch && git push origin main --tags",
|
|
68
|
+
"release:minor": "git add -A && git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates' && pnpm version minor && git push origin main --tags",
|
|
69
|
+
"release:major": "git add -A && git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates' && pnpm version major && git push origin main --tags"
|
|
70
|
+
}
|
|
71
|
+
}
|