@fifine/aim-studio 0.0.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/LICENSE +21 -0
- package/README.md +159 -0
- package/bin/aim.js +3 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +89 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/init.d.ts +13 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +513 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/update.d.ts +27 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +1275 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/configurators/claude.d.ts +32 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +98 -0
- package/dist/configurators/claude.js.map +1 -0
- package/dist/configurators/index.d.ts +51 -0
- package/dist/configurators/index.d.ts.map +1 -0
- package/dist/configurators/index.js +113 -0
- package/dist/configurators/index.js.map +1 -0
- package/dist/configurators/shared.d.ts +12 -0
- package/dist/configurators/shared.d.ts.map +1 -0
- package/dist/configurators/shared.js +21 -0
- package/dist/configurators/shared.js.map +1 -0
- package/dist/configurators/workflow.d.ts +28 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +147 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/constants/paths.d.ts +68 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +77 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/constants/version.d.ts +9 -0
- package/dist/constants/version.d.ts.map +1 -0
- package/dist/constants/version.js +15 -0
- package/dist/constants/version.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/migrations/index.d.ts +54 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +160 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/manifests/0.0.1.json +9 -0
- package/dist/migrations/manifests/0.1.9.json +30 -0
- package/dist/migrations/manifests/0.2.0.json +49 -0
- package/dist/migrations/manifests/0.2.12.json +9 -0
- package/dist/migrations/manifests/0.2.13.json +9 -0
- package/dist/migrations/manifests/0.2.14.json +175 -0
- package/dist/migrations/manifests/0.2.15.json +33 -0
- package/dist/migrations/manifests/0.3.0-beta.0.json +278 -0
- package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
- package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
- package/dist/templates/CLAUDE.md +71 -0
- package/dist/templates/aim/gitignore.txt +29 -0
- package/dist/templates/aim/index.d.ts +49 -0
- package/dist/templates/aim/index.d.ts.map +1 -0
- package/dist/templates/aim/index.js +92 -0
- package/dist/templates/aim/index.js.map +1 -0
- package/dist/templates/aim/scripts/__init__.py +5 -0
- package/dist/templates/aim/scripts/add_session.py +392 -0
- package/dist/templates/aim/scripts/common/__init__.py +80 -0
- package/dist/templates/aim/scripts/common/cli_adapter.py +435 -0
- package/dist/templates/aim/scripts/common/developer.py +190 -0
- package/dist/templates/aim/scripts/common/git_context.py +383 -0
- package/dist/templates/aim/scripts/common/paths.py +347 -0
- package/dist/templates/aim/scripts/common/phase.py +253 -0
- package/dist/templates/aim/scripts/common/registry.py +366 -0
- package/dist/templates/aim/scripts/common/task_queue.py +255 -0
- package/dist/templates/aim/scripts/common/task_utils.py +178 -0
- package/dist/templates/aim/scripts/common/worktree.py +219 -0
- package/dist/templates/aim/scripts/create_bootstrap.py +290 -0
- package/dist/templates/aim/scripts/get_context.py +16 -0
- package/dist/templates/aim/scripts/get_developer.py +26 -0
- package/dist/templates/aim/scripts/init_developer.py +51 -0
- package/dist/templates/aim/scripts/multi_agent/__init__.py +5 -0
- package/dist/templates/aim/scripts/multi_agent/cleanup.py +403 -0
- package/dist/templates/aim/scripts/multi_agent/create_pr.py +329 -0
- package/dist/templates/aim/scripts/multi_agent/plan.py +233 -0
- package/dist/templates/aim/scripts/multi_agent/start.py +461 -0
- package/dist/templates/aim/scripts/multi_agent/status.py +817 -0
- package/dist/templates/aim/scripts/task.py +1068 -0
- package/dist/templates/aim/scripts-shell-archive/add-session.sh +384 -0
- package/dist/templates/aim/scripts-shell-archive/common/developer.sh +129 -0
- package/dist/templates/aim/scripts-shell-archive/common/git-context.sh +263 -0
- package/dist/templates/aim/scripts-shell-archive/common/paths.sh +208 -0
- package/dist/templates/aim/scripts-shell-archive/common/phase.sh +150 -0
- package/dist/templates/aim/scripts-shell-archive/common/registry.sh +247 -0
- package/dist/templates/aim/scripts-shell-archive/common/task-queue.sh +142 -0
- package/dist/templates/aim/scripts-shell-archive/common/task-utils.sh +151 -0
- package/dist/templates/aim/scripts-shell-archive/common/worktree.sh +128 -0
- package/dist/templates/aim/scripts-shell-archive/create-bootstrap.sh +299 -0
- package/dist/templates/aim/scripts-shell-archive/get-context.sh +7 -0
- package/dist/templates/aim/scripts-shell-archive/get-developer.sh +15 -0
- package/dist/templates/aim/scripts-shell-archive/init-developer.sh +34 -0
- package/dist/templates/aim/scripts-shell-archive/multi-agent/cleanup.sh +396 -0
- package/dist/templates/aim/scripts-shell-archive/multi-agent/create-pr.sh +241 -0
- package/dist/templates/aim/scripts-shell-archive/multi-agent/plan.sh +207 -0
- package/dist/templates/aim/scripts-shell-archive/multi-agent/start.sh +317 -0
- package/dist/templates/aim/scripts-shell-archive/multi-agent/status.sh +828 -0
- package/dist/templates/aim/scripts-shell-archive/task.sh +1204 -0
- package/dist/templates/aim/tasks/.gitkeep +0 -0
- package/dist/templates/aim/workflow.md +258 -0
- package/dist/templates/aim/worktree.yaml +47 -0
- package/dist/templates/claude/agents/check.md +122 -0
- package/dist/templates/claude/agents/debug.md +106 -0
- package/dist/templates/claude/agents/dispatch.md +230 -0
- package/dist/templates/claude/agents/implement.md +96 -0
- package/dist/templates/claude/agents/plan.md +396 -0
- package/dist/templates/claude/agents/research.md +120 -0
- package/dist/templates/claude/agents/story.md +53 -0
- package/dist/templates/claude/commands/aim/before-backend-dev.md +13 -0
- package/dist/templates/claude/commands/aim/before-frontend-dev.md +13 -0
- package/dist/templates/claude/commands/aim/break-loop.md +153 -0
- package/dist/templates/claude/commands/aim/check-backend.md +13 -0
- package/dist/templates/claude/commands/aim/check-cross-layer.md +153 -0
- package/dist/templates/claude/commands/aim/check-frontend.md +13 -0
- package/dist/templates/claude/commands/aim/check-story.md +59 -0
- package/dist/templates/claude/commands/aim/create-command.md +154 -0
- package/dist/templates/claude/commands/aim/export.md +187 -0
- package/dist/templates/claude/commands/aim/finish-work.md +104 -0
- package/dist/templates/claude/commands/aim/integrate-skill.md +219 -0
- package/dist/templates/claude/commands/aim/onboard.md +358 -0
- package/dist/templates/claude/commands/aim/parallel.md +217 -0
- package/dist/templates/claude/commands/aim/portrait.md +170 -0
- package/dist/templates/claude/commands/aim/record-session.md +92 -0
- package/dist/templates/claude/commands/aim/start.md +112 -0
- package/dist/templates/claude/commands/aim/story.md +140 -0
- package/dist/templates/claude/commands/aim/update-spec.md +285 -0
- package/dist/templates/claude/commands/aim/visualize.md +182 -0
- package/dist/templates/claude/commands/trellis/before-backend-dev.md +13 -0
- package/dist/templates/claude/commands/trellis/before-frontend-dev.md +13 -0
- package/dist/templates/claude/commands/trellis/break-loop.md +125 -0
- package/dist/templates/claude/commands/trellis/check-backend.md +13 -0
- package/dist/templates/claude/commands/trellis/check-cross-layer.md +153 -0
- package/dist/templates/claude/commands/trellis/check-frontend.md +13 -0
- package/dist/templates/claude/commands/trellis/create-command.md +154 -0
- package/dist/templates/claude/commands/trellis/finish-work.md +129 -0
- package/dist/templates/claude/commands/trellis/integrate-skill.md +219 -0
- package/dist/templates/claude/commands/trellis/onboard.md +358 -0
- package/dist/templates/claude/commands/trellis/parallel.md +193 -0
- package/dist/templates/claude/commands/trellis/record-session.md +62 -0
- package/dist/templates/claude/commands/trellis/start.md +280 -0
- package/dist/templates/claude/commands/trellis/update-spec.md +285 -0
- package/dist/templates/claude/hooks/inject-subagent-context.py +772 -0
- package/dist/templates/claude/hooks/ralph-loop.py +388 -0
- package/dist/templates/claude/hooks/session-start.py +142 -0
- package/dist/templates/claude/index.d.ts +54 -0
- package/dist/templates/claude/index.d.ts.map +1 -0
- package/dist/templates/claude/index.js +85 -0
- package/dist/templates/claude/index.js.map +1 -0
- package/dist/templates/claude/settings.json +41 -0
- package/dist/templates/extract.d.ts +68 -0
- package/dist/templates/extract.d.ts.map +1 -0
- package/dist/templates/extract.js +128 -0
- package/dist/templates/extract.js.map +1 -0
- package/dist/templates/markdown/agents.md +25 -0
- package/dist/templates/markdown/gitignore.txt +12 -0
- package/dist/templates/markdown/index.d.ts +32 -0
- package/dist/templates/markdown/index.d.ts.map +1 -0
- package/dist/templates/markdown/index.js +58 -0
- package/dist/templates/markdown/index.js.map +1 -0
- package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/index.md +40 -0
- package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
- package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/script-conventions.md +467 -0
- package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
- package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
- package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md +118 -0
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +92 -0
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +94 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md +394 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +319 -0
- package/dist/templates/markdown/spec/guides/index.md.txt +89 -0
- package/dist/templates/markdown/spec/story/character.md.txt +95 -0
- package/dist/templates/markdown/spec/story/index.md.txt +31 -0
- package/dist/templates/markdown/spec/story/script.md.txt +313 -0
- package/dist/templates/markdown/spec/story/world.md.txt +92 -0
- package/dist/templates/markdown/workspace-index.md +123 -0
- package/dist/templates/markdown/worktree.yaml.txt +58 -0
- package/dist/templates/trellis/gitignore.txt +29 -0
- package/dist/templates/trellis/index.d.ts +49 -0
- package/dist/templates/trellis/index.d.ts.map +1 -0
- package/dist/templates/trellis/index.js +92 -0
- package/dist/templates/trellis/index.js.map +1 -0
- package/dist/templates/trellis/scripts/__init__.py +5 -0
- package/dist/templates/trellis/scripts/add_session.py +392 -0
- package/dist/templates/trellis/scripts/common/__init__.py +80 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +435 -0
- package/dist/templates/trellis/scripts/common/developer.py +190 -0
- package/dist/templates/trellis/scripts/common/git_context.py +383 -0
- package/dist/templates/trellis/scripts/common/paths.py +347 -0
- package/dist/templates/trellis/scripts/common/phase.py +253 -0
- package/dist/templates/trellis/scripts/common/registry.py +366 -0
- package/dist/templates/trellis/scripts/common/task_queue.py +255 -0
- package/dist/templates/trellis/scripts/common/task_utils.py +178 -0
- package/dist/templates/trellis/scripts/common/worktree.py +219 -0
- package/dist/templates/trellis/scripts/create_bootstrap.py +290 -0
- package/dist/templates/trellis/scripts/get_context.py +16 -0
- package/dist/templates/trellis/scripts/get_developer.py +26 -0
- package/dist/templates/trellis/scripts/init_developer.py +51 -0
- package/dist/templates/trellis/scripts/multi_agent/__init__.py +5 -0
- package/dist/templates/trellis/scripts/multi_agent/cleanup.py +403 -0
- package/dist/templates/trellis/scripts/multi_agent/create_pr.py +329 -0
- package/dist/templates/trellis/scripts/multi_agent/plan.py +233 -0
- package/dist/templates/trellis/scripts/multi_agent/start.py +461 -0
- package/dist/templates/trellis/scripts/multi_agent/status.py +817 -0
- package/dist/templates/trellis/scripts/task.py +1056 -0
- package/dist/templates/trellis/scripts-shell-archive/add-session.sh +384 -0
- package/dist/templates/trellis/scripts-shell-archive/common/developer.sh +129 -0
- package/dist/templates/trellis/scripts-shell-archive/common/git-context.sh +263 -0
- package/dist/templates/trellis/scripts-shell-archive/common/paths.sh +208 -0
- package/dist/templates/trellis/scripts-shell-archive/common/phase.sh +150 -0
- package/dist/templates/trellis/scripts-shell-archive/common/registry.sh +247 -0
- package/dist/templates/trellis/scripts-shell-archive/common/task-queue.sh +142 -0
- package/dist/templates/trellis/scripts-shell-archive/common/task-utils.sh +151 -0
- package/dist/templates/trellis/scripts-shell-archive/common/worktree.sh +128 -0
- package/dist/templates/trellis/scripts-shell-archive/create-bootstrap.sh +299 -0
- package/dist/templates/trellis/scripts-shell-archive/get-context.sh +7 -0
- package/dist/templates/trellis/scripts-shell-archive/get-developer.sh +15 -0
- package/dist/templates/trellis/scripts-shell-archive/init-developer.sh +34 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/cleanup.sh +396 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/create-pr.sh +241 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/plan.sh +207 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/start.sh +317 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/status.sh +828 -0
- package/dist/templates/trellis/scripts-shell-archive/task.sh +1204 -0
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +416 -0
- package/dist/templates/trellis/worktree.yaml +47 -0
- package/dist/types/ai-tools.d.ts +48 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +32 -0
- package/dist/types/ai-tools.js.map +1 -0
- package/dist/types/migration.d.ts +86 -0
- package/dist/types/migration.d.ts.map +1 -0
- package/dist/types/migration.js +8 -0
- package/dist/types/migration.js.map +1 -0
- package/dist/utils/compare-versions.d.ts +12 -0
- package/dist/utils/compare-versions.d.ts.map +1 -0
- package/dist/utils/compare-versions.js +76 -0
- package/dist/utils/compare-versions.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 +188 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/dist/utils/template-fetcher.d.ts +51 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -0
- package/dist/utils/template-fetcher.js +174 -0
- package/dist/utils/template-fetcher.js.map +1 -0
- package/dist/utils/template-hash.d.ts +78 -0
- package/dist/utils/template-hash.d.ts.map +1 -0
- package/dist/utils/template-hash.js +239 -0
- package/dist/utils/template-hash.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote template fetcher for AIM Studio CLI
|
|
3
|
+
*
|
|
4
|
+
* Fetches spec templates from the official docs repository:
|
|
5
|
+
* https://github.com/mindfold-ai/docs/tree/main/marketplace
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import os from "node:os";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { downloadTemplate } from "giget";
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Constants
|
|
13
|
+
// =============================================================================
|
|
14
|
+
const TEMPLATE_INDEX_URL = "https://raw.githubusercontent.com/mindfold-ai/docs/main/marketplace/index.json";
|
|
15
|
+
const TEMPLATE_REPO = "gh:mindfold-ai/docs";
|
|
16
|
+
/** Map template type to installation path */
|
|
17
|
+
const INSTALL_PATHS = {
|
|
18
|
+
spec: ".aim-studio/spec",
|
|
19
|
+
skill: ".agents/skills",
|
|
20
|
+
command: ".claude/commands",
|
|
21
|
+
full: ".", // Entire project root
|
|
22
|
+
};
|
|
23
|
+
// =============================================================================
|
|
24
|
+
// Fetch Template Index
|
|
25
|
+
// =============================================================================
|
|
26
|
+
/**
|
|
27
|
+
* Fetch available templates from the remote index
|
|
28
|
+
* Returns empty array on network error (allows fallback to blank)
|
|
29
|
+
*/
|
|
30
|
+
export async function fetchTemplateIndex() {
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch(TEMPLATE_INDEX_URL);
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
throw new Error(`HTTP ${res.status}`);
|
|
35
|
+
}
|
|
36
|
+
const index = (await res.json());
|
|
37
|
+
return index.templates;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Network error - return empty array, caller will fallback to blank
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Find a template by ID from the index
|
|
46
|
+
*/
|
|
47
|
+
export async function findTemplate(templateId) {
|
|
48
|
+
const templates = await fetchTemplateIndex();
|
|
49
|
+
return templates.find((t) => t.id === templateId) ?? null;
|
|
50
|
+
}
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// Download Template
|
|
53
|
+
// =============================================================================
|
|
54
|
+
/**
|
|
55
|
+
* Get the installation path for a template type
|
|
56
|
+
*/
|
|
57
|
+
export function getInstallPath(cwd, templateType) {
|
|
58
|
+
const relativePath = INSTALL_PATHS[templateType] || INSTALL_PATHS.spec;
|
|
59
|
+
return path.join(cwd, relativePath);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Download a template with the specified strategy
|
|
63
|
+
*
|
|
64
|
+
* @param templatePath - Path in the docs repo (e.g., "marketplace/specs/electron-fullstack")
|
|
65
|
+
* @param destDir - Destination directory
|
|
66
|
+
* @param strategy - How to handle existing directory: skip, overwrite, or append
|
|
67
|
+
* @returns true if template was downloaded, false if skipped
|
|
68
|
+
*/
|
|
69
|
+
export async function downloadWithStrategy(templatePath, destDir, strategy) {
|
|
70
|
+
const exists = fs.existsSync(destDir);
|
|
71
|
+
// skip: Directory exists, don't download
|
|
72
|
+
if (strategy === "skip" && exists) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
// overwrite: Delete existing directory first
|
|
76
|
+
if (strategy === "overwrite" && exists) {
|
|
77
|
+
await fs.promises.rm(destDir, { recursive: true });
|
|
78
|
+
}
|
|
79
|
+
// append: Download to temp dir, then merge missing files
|
|
80
|
+
if (strategy === "append" && exists) {
|
|
81
|
+
const tempDir = path.join(os.tmpdir(), `aim-template-${Date.now()}`);
|
|
82
|
+
try {
|
|
83
|
+
await downloadTemplate(`${TEMPLATE_REPO}/${templatePath}`, {
|
|
84
|
+
dir: tempDir,
|
|
85
|
+
preferOffline: true,
|
|
86
|
+
});
|
|
87
|
+
await copyMissing(tempDir, destDir);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
// Clean up temp directory
|
|
91
|
+
await fs.promises.rm(tempDir, { recursive: true, force: true });
|
|
92
|
+
}
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
// Default: Direct download (for new directory or after overwrite)
|
|
96
|
+
await downloadTemplate(`${TEMPLATE_REPO}/${templatePath}`, {
|
|
97
|
+
dir: destDir,
|
|
98
|
+
preferOffline: true,
|
|
99
|
+
});
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Copy only files that don't exist in the destination
|
|
104
|
+
*/
|
|
105
|
+
async function copyMissing(src, dest) {
|
|
106
|
+
// Ensure destination exists
|
|
107
|
+
if (!fs.existsSync(dest)) {
|
|
108
|
+
await fs.promises.mkdir(dest, { recursive: true });
|
|
109
|
+
}
|
|
110
|
+
const entries = await fs.promises.readdir(src, { withFileTypes: true });
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
const srcPath = path.join(src, entry.name);
|
|
113
|
+
const destPath = path.join(dest, entry.name);
|
|
114
|
+
if (entry.isDirectory()) {
|
|
115
|
+
// Recursively copy missing files in subdirectory
|
|
116
|
+
await copyMissing(srcPath, destPath);
|
|
117
|
+
}
|
|
118
|
+
else if (!fs.existsSync(destPath)) {
|
|
119
|
+
// Only copy if file doesn't exist
|
|
120
|
+
await fs.promises.copyFile(srcPath, destPath);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Download a template by ID
|
|
126
|
+
*
|
|
127
|
+
* @param cwd - Current working directory
|
|
128
|
+
* @param templateId - Template ID from the index
|
|
129
|
+
* @param strategy - How to handle existing directory
|
|
130
|
+
* @returns Object with success status and message
|
|
131
|
+
*/
|
|
132
|
+
export async function downloadTemplateById(cwd, templateId, strategy) {
|
|
133
|
+
// Find template in index
|
|
134
|
+
const template = await findTemplate(templateId);
|
|
135
|
+
if (!template) {
|
|
136
|
+
return {
|
|
137
|
+
success: false,
|
|
138
|
+
message: `Template "${templateId}" not found`,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// Only support spec type in MVP
|
|
142
|
+
if (template.type !== "spec") {
|
|
143
|
+
return {
|
|
144
|
+
success: false,
|
|
145
|
+
message: `Template type "${template.type}" is not supported yet (only "spec" is supported)`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
// Get destination path
|
|
149
|
+
const destDir = getInstallPath(cwd, template.type);
|
|
150
|
+
// Check if directory exists for skip strategy
|
|
151
|
+
if (strategy === "skip" && fs.existsSync(destDir)) {
|
|
152
|
+
return {
|
|
153
|
+
success: true,
|
|
154
|
+
skipped: true,
|
|
155
|
+
message: `Skipped: ${destDir} already exists`,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
// Download template
|
|
159
|
+
try {
|
|
160
|
+
await downloadWithStrategy(template.path, destDir, strategy);
|
|
161
|
+
return {
|
|
162
|
+
success: true,
|
|
163
|
+
message: `Downloaded template "${templateId}" to ${destDir}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
168
|
+
return {
|
|
169
|
+
success: false,
|
|
170
|
+
message: `Failed to download template: ${errorMessage}`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=template-fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-fetcher.js","sourceRoot":"","sources":["../../src/utils/template-fetcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template hash utilities for detecting user modifications
|
|
3
|
+
*
|
|
4
|
+
* Stores SHA256 hashes of template files at install time.
|
|
5
|
+
* Used to determine if users have modified templates.
|
|
6
|
+
*/
|
|
7
|
+
import type { TemplateHashes } from "../types/migration.js";
|
|
8
|
+
/**
|
|
9
|
+
* Compute SHA256 hash of content
|
|
10
|
+
*/
|
|
11
|
+
export declare function computeHash(content: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Load stored template hashes
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadHashes(cwd: string): TemplateHashes;
|
|
16
|
+
/**
|
|
17
|
+
* Save template hashes
|
|
18
|
+
*/
|
|
19
|
+
export declare function saveHashes(cwd: string, hashes: TemplateHashes): void;
|
|
20
|
+
/**
|
|
21
|
+
* Update hashes for specific files
|
|
22
|
+
*
|
|
23
|
+
* @param cwd - Working directory
|
|
24
|
+
* @param files - Map of relative paths to file contents
|
|
25
|
+
*/
|
|
26
|
+
export declare function updateHashes(cwd: string, files: Map<string, string>): void;
|
|
27
|
+
/**
|
|
28
|
+
* Update hash for a single file by reading its current content
|
|
29
|
+
*/
|
|
30
|
+
export declare function updateHashFromFile(cwd: string, relativePath: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Remove hash entry for a file (e.g., after deletion)
|
|
33
|
+
*/
|
|
34
|
+
export declare function removeHash(cwd: string, relativePath: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* Rename hash entry (used after file rename)
|
|
37
|
+
*/
|
|
38
|
+
export declare function renameHash(cwd: string, oldPath: string, newPath: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a template file has been modified by the user
|
|
41
|
+
*
|
|
42
|
+
* @param cwd - Working directory
|
|
43
|
+
* @param relativePath - Relative path to the file
|
|
44
|
+
* @param hashes - Stored template hashes
|
|
45
|
+
* @returns true if file has been modified from template, false otherwise
|
|
46
|
+
*/
|
|
47
|
+
export declare function isTemplateModified(cwd: string, relativePath: string, hashes: TemplateHashes): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a file matches its original template content
|
|
50
|
+
* (Useful for determining if a file can be safely auto-migrated)
|
|
51
|
+
*
|
|
52
|
+
* @param cwd - Working directory
|
|
53
|
+
* @param relativePath - Relative path to the file
|
|
54
|
+
* @param originalContent - Original template content
|
|
55
|
+
* @returns true if file matches original template
|
|
56
|
+
*/
|
|
57
|
+
export declare function matchesOriginalTemplate(cwd: string, relativePath: string, originalContent: string): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Get modification status for multiple files
|
|
60
|
+
*
|
|
61
|
+
* @param cwd - Working directory
|
|
62
|
+
* @param relativePaths - Array of relative paths to check
|
|
63
|
+
* @param hashes - Stored template hashes
|
|
64
|
+
* @returns Map of path to modification status
|
|
65
|
+
*/
|
|
66
|
+
export declare function getModificationStatus(cwd: string, relativePaths: string[], hashes: TemplateHashes): Map<string, boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Initialize template hashes after init
|
|
69
|
+
*
|
|
70
|
+
* Scans all template directories and computes hashes for files.
|
|
71
|
+
* This should be called at the end of `trellis init` to enable
|
|
72
|
+
* modification detection on subsequent updates.
|
|
73
|
+
*
|
|
74
|
+
* @param cwd - Working directory
|
|
75
|
+
* @returns Number of files hashed
|
|
76
|
+
*/
|
|
77
|
+
export declare function initializeHashes(cwd: string): number;
|
|
78
|
+
//# sourceMappingURL=template-hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-hash.d.ts","sourceRoot":"","sources":["../../src/utils/template-hash.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK5D;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AASD;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAYtD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,IAAI,CAGpE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAU1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAU1E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,CAIlE;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,IAAI,CAON;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAmBT;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,OAAO,CAST;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EAAE,EACvB,MAAM,EAAE,cAAc,GACrB,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAQtB;AAsED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsBpD"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template hash utilities for detecting user modifications
|
|
3
|
+
*
|
|
4
|
+
* Stores SHA256 hashes of template files at install time.
|
|
5
|
+
* Used to determine if users have modified templates.
|
|
6
|
+
*/
|
|
7
|
+
import { createHash } from "node:crypto";
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import { DIR_NAMES } from "../constants/paths.js";
|
|
11
|
+
import { ALL_MANAGED_DIRS } from "../configurators/index.js";
|
|
12
|
+
/** File name for storing template hashes */
|
|
13
|
+
const HASHES_FILE = ".template-hashes.json";
|
|
14
|
+
/**
|
|
15
|
+
* Compute SHA256 hash of content
|
|
16
|
+
*/
|
|
17
|
+
export function computeHash(content) {
|
|
18
|
+
return createHash("sha256").update(content, "utf-8").digest("hex");
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get path to the hashes file
|
|
22
|
+
*/
|
|
23
|
+
function getHashesPath(cwd) {
|
|
24
|
+
return path.join(cwd, DIR_NAMES.WORKFLOW, HASHES_FILE);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load stored template hashes
|
|
28
|
+
*/
|
|
29
|
+
export function loadHashes(cwd) {
|
|
30
|
+
const hashesPath = getHashesPath(cwd);
|
|
31
|
+
if (!fs.existsSync(hashesPath)) {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const content = fs.readFileSync(hashesPath, "utf-8");
|
|
36
|
+
return JSON.parse(content);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Save template hashes
|
|
44
|
+
*/
|
|
45
|
+
export function saveHashes(cwd, hashes) {
|
|
46
|
+
const hashesPath = getHashesPath(cwd);
|
|
47
|
+
fs.writeFileSync(hashesPath, JSON.stringify(hashes, null, 2));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Update hashes for specific files
|
|
51
|
+
*
|
|
52
|
+
* @param cwd - Working directory
|
|
53
|
+
* @param files - Map of relative paths to file contents
|
|
54
|
+
*/
|
|
55
|
+
export function updateHashes(cwd, files) {
|
|
56
|
+
const hashes = loadHashes(cwd);
|
|
57
|
+
for (const [relativePath, content] of files) {
|
|
58
|
+
// Normalize path to forward slashes for portable hash keys
|
|
59
|
+
const portablePath = relativePath.split(path.sep).join("/");
|
|
60
|
+
hashes[portablePath] = computeHash(content);
|
|
61
|
+
}
|
|
62
|
+
saveHashes(cwd, hashes);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Update hash for a single file by reading its current content
|
|
66
|
+
*/
|
|
67
|
+
export function updateHashFromFile(cwd, relativePath) {
|
|
68
|
+
const fullPath = path.join(cwd, relativePath);
|
|
69
|
+
if (!fs.existsSync(fullPath)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
73
|
+
const hashes = loadHashes(cwd);
|
|
74
|
+
hashes[relativePath] = computeHash(content);
|
|
75
|
+
saveHashes(cwd, hashes);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Remove hash entry for a file (e.g., after deletion)
|
|
79
|
+
*/
|
|
80
|
+
export function removeHash(cwd, relativePath) {
|
|
81
|
+
const hashes = loadHashes(cwd);
|
|
82
|
+
const { [relativePath]: _, ...rest } = hashes;
|
|
83
|
+
saveHashes(cwd, rest);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Rename hash entry (used after file rename)
|
|
87
|
+
*/
|
|
88
|
+
export function renameHash(cwd, oldPath, newPath) {
|
|
89
|
+
const hashes = loadHashes(cwd);
|
|
90
|
+
if (hashes[oldPath]) {
|
|
91
|
+
const { [oldPath]: oldValue, ...rest } = hashes;
|
|
92
|
+
rest[newPath] = oldValue;
|
|
93
|
+
saveHashes(cwd, rest);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Check if a template file has been modified by the user
|
|
98
|
+
*
|
|
99
|
+
* @param cwd - Working directory
|
|
100
|
+
* @param relativePath - Relative path to the file
|
|
101
|
+
* @param hashes - Stored template hashes
|
|
102
|
+
* @returns true if file has been modified from template, false otherwise
|
|
103
|
+
*/
|
|
104
|
+
export function isTemplateModified(cwd, relativePath, hashes) {
|
|
105
|
+
const fullPath = path.join(cwd, relativePath);
|
|
106
|
+
// If file doesn't exist, can't be modified
|
|
107
|
+
if (!fs.existsSync(fullPath)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
// If we don't have a stored hash, assume it's modified (conservative)
|
|
111
|
+
const storedHash = hashes[relativePath];
|
|
112
|
+
if (!storedHash) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
// Compare current content hash with stored hash
|
|
116
|
+
const currentContent = fs.readFileSync(fullPath, "utf-8");
|
|
117
|
+
const currentHash = computeHash(currentContent);
|
|
118
|
+
return currentHash !== storedHash;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if a file matches its original template content
|
|
122
|
+
* (Useful for determining if a file can be safely auto-migrated)
|
|
123
|
+
*
|
|
124
|
+
* @param cwd - Working directory
|
|
125
|
+
* @param relativePath - Relative path to the file
|
|
126
|
+
* @param originalContent - Original template content
|
|
127
|
+
* @returns true if file matches original template
|
|
128
|
+
*/
|
|
129
|
+
export function matchesOriginalTemplate(cwd, relativePath, originalContent) {
|
|
130
|
+
const fullPath = path.join(cwd, relativePath);
|
|
131
|
+
if (!fs.existsSync(fullPath)) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
const currentContent = fs.readFileSync(fullPath, "utf-8");
|
|
135
|
+
return currentContent === originalContent;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get modification status for multiple files
|
|
139
|
+
*
|
|
140
|
+
* @param cwd - Working directory
|
|
141
|
+
* @param relativePaths - Array of relative paths to check
|
|
142
|
+
* @param hashes - Stored template hashes
|
|
143
|
+
* @returns Map of path to modification status
|
|
144
|
+
*/
|
|
145
|
+
export function getModificationStatus(cwd, relativePaths, hashes) {
|
|
146
|
+
const result = new Map();
|
|
147
|
+
for (const relativePath of relativePaths) {
|
|
148
|
+
result.set(relativePath, isTemplateModified(cwd, relativePath, hashes));
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Directories to scan for template files during init (derived from platform registry)
|
|
154
|
+
*/
|
|
155
|
+
const TEMPLATE_DIRS = ALL_MANAGED_DIRS;
|
|
156
|
+
/**
|
|
157
|
+
* Patterns to exclude from hash tracking
|
|
158
|
+
*/
|
|
159
|
+
const EXCLUDE_FROM_HASH = [
|
|
160
|
+
".template-hashes.json", // Hash file itself
|
|
161
|
+
".version", // Version file
|
|
162
|
+
".gitignore", // Git ignore files
|
|
163
|
+
".developer", // Developer identity file
|
|
164
|
+
"workspace/", // Workspace files (user data)
|
|
165
|
+
"tasks/", // Task files (user data)
|
|
166
|
+
".current-task", // Current task marker (file, not directory)
|
|
167
|
+
"spec/frontend/", // User-filled spec files
|
|
168
|
+
"spec/backend/", // User-filled spec files
|
|
169
|
+
".backup-", // Backup directories
|
|
170
|
+
];
|
|
171
|
+
/**
|
|
172
|
+
* Check if a path should be excluded from hash tracking
|
|
173
|
+
*/
|
|
174
|
+
function shouldExcludeFromHash(relativePath) {
|
|
175
|
+
// Normalize to forward slashes for pattern matching
|
|
176
|
+
const normalizedPath = relativePath.split(path.sep).join("/");
|
|
177
|
+
for (const pattern of EXCLUDE_FROM_HASH) {
|
|
178
|
+
if (normalizedPath.includes(pattern)) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Recursively collect all files in a directory
|
|
186
|
+
*/
|
|
187
|
+
function collectFiles(cwd, dir, relativeTo = "") {
|
|
188
|
+
const fullDir = path.join(cwd, dir);
|
|
189
|
+
if (!fs.existsSync(fullDir)) {
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
const files = [];
|
|
193
|
+
const entries = fs.readdirSync(fullDir, { withFileTypes: true });
|
|
194
|
+
for (const entry of entries) {
|
|
195
|
+
const relativePath = path.join(dir, entry.name);
|
|
196
|
+
if (shouldExcludeFromHash(relativePath)) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
if (entry.isDirectory()) {
|
|
200
|
+
files.push(...collectFiles(cwd, relativePath, relativeTo));
|
|
201
|
+
}
|
|
202
|
+
else if (entry.isFile()) {
|
|
203
|
+
files.push(relativePath);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return files;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Initialize template hashes after init
|
|
210
|
+
*
|
|
211
|
+
* Scans all template directories and computes hashes for files.
|
|
212
|
+
* This should be called at the end of `trellis init` to enable
|
|
213
|
+
* modification detection on subsequent updates.
|
|
214
|
+
*
|
|
215
|
+
* @param cwd - Working directory
|
|
216
|
+
* @returns Number of files hashed
|
|
217
|
+
*/
|
|
218
|
+
export function initializeHashes(cwd) {
|
|
219
|
+
const hashes = {};
|
|
220
|
+
// Collect all template files
|
|
221
|
+
for (const dir of TEMPLATE_DIRS) {
|
|
222
|
+
const files = collectFiles(cwd, dir);
|
|
223
|
+
for (const relativePath of files) {
|
|
224
|
+
const fullPath = path.join(cwd, relativePath);
|
|
225
|
+
try {
|
|
226
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
227
|
+
// Normalize path to forward slashes for portable hash keys
|
|
228
|
+
const portablePath = relativePath.split(path.sep).join("/");
|
|
229
|
+
hashes[portablePath] = computeHash(content);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// Skip files that can't be read (binary, etc.)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
saveHashes(cwd, hashes);
|
|
237
|
+
return Object.keys(hashes).length;
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=template-hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-hash.js","sourceRoot":"","sources":["../../src/utils/template-hash.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fifine/aim-studio",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "AIM Studio — Specialized CLI for AI comic and drama generation. Formerly Trellis.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"aim": "bin/aim.js"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc && pnpm run copy-templates",
|
|
16
|
+
"copy-templates": "node scripts/copy-templates.js",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"start": "node ./dist/cli/index.js",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"test:coverage": "vitest run --coverage",
|
|
22
|
+
"lint": "eslint src/ test/",
|
|
23
|
+
"lint:fix": "eslint src/ test/ --fix",
|
|
24
|
+
"format": "prettier --write src/",
|
|
25
|
+
"format:check": "prettier --check src/",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"lint:py": "basedpyright",
|
|
28
|
+
"lint:all": "pnpm lint && pnpm lint:py",
|
|
29
|
+
"prepare": "husky",
|
|
30
|
+
"prepublishOnly": "pnpm run build",
|
|
31
|
+
"release": "git add -A && git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates' && pnpm version patch && git push origin main --tags",
|
|
32
|
+
"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",
|
|
33
|
+
"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",
|
|
34
|
+
"release:beta": "git add -A && git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates' && pnpm version prerelease --preid beta && git push origin HEAD --tags",
|
|
35
|
+
"release:rc": "git add -A && git diff-index --quiet HEAD || git commit -m 'chore: pre-release updates' && pnpm version prerelease --preid rc && git push origin HEAD --tags",
|
|
36
|
+
"manifest": "node scripts/create-manifest.js"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"ai",
|
|
40
|
+
"workflow",
|
|
41
|
+
"cursor",
|
|
42
|
+
"claude",
|
|
43
|
+
"iflow",
|
|
44
|
+
"cli",
|
|
45
|
+
"developer-tools",
|
|
46
|
+
"agent",
|
|
47
|
+
"memory",
|
|
48
|
+
"trellis"
|
|
49
|
+
],
|
|
50
|
+
"author": "Mindfold LLC",
|
|
51
|
+
"license": "AGPL-3.0-only",
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"chalk": "^5.3.0",
|
|
54
|
+
"commander": "^12.1.0",
|
|
55
|
+
"figlet": "^1.9.4",
|
|
56
|
+
"giget": "^3.1.1",
|
|
57
|
+
"inquirer": "^9.3.7"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@eslint/js": "^9.18.0",
|
|
61
|
+
"@types/figlet": "^1.7.0",
|
|
62
|
+
"@types/inquirer": "^9.0.7",
|
|
63
|
+
"@types/node": "^20.17.10",
|
|
64
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
65
|
+
"basedpyright": "^1.37.2",
|
|
66
|
+
"eslint": "^9.18.0",
|
|
67
|
+
"husky": "^9.1.7",
|
|
68
|
+
"lint-staged": "^16.2.7",
|
|
69
|
+
"prettier": "^3.4.2",
|
|
70
|
+
"typescript": "^5.7.2",
|
|
71
|
+
"typescript-eslint": "^8.21.0",
|
|
72
|
+
"vitest": "^4.0.18"
|
|
73
|
+
},
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=18.0.0"
|
|
76
|
+
},
|
|
77
|
+
"files": [
|
|
78
|
+
"dist",
|
|
79
|
+
"bin",
|
|
80
|
+
"README.md",
|
|
81
|
+
"LICENSE.md"
|
|
82
|
+
],
|
|
83
|
+
"repository": {
|
|
84
|
+
"type": "git",
|
|
85
|
+
"url": "https://github.com/mindfold-ai/aim-studio.git"
|
|
86
|
+
}
|
|
87
|
+
}
|