@blxzer/cursor-trellis 0.2.9 → 0.3.2
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/CHANGELOG.md +94 -0
- package/README.md +85 -19
- package/README.zh-CN.md +60 -21
- package/bin/smart-search.js +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +46 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/capability-smoke.d.ts +24 -0
- package/dist/commands/capability-smoke.d.ts.map +1 -0
- package/dist/commands/capability-smoke.js +83 -0
- package/dist/commands/capability-smoke.js.map +1 -0
- package/dist/commands/channel/agent-loader.d.ts +1 -1
- package/dist/commands/channel/agent-loader.js +4 -4
- package/dist/commands/channel/agent-loader.js.map +1 -1
- package/dist/commands/channel/guard.d.ts +2 -2
- package/dist/commands/channel/guard.js +3 -3
- package/dist/commands/channel/guard.js.map +1 -1
- package/dist/commands/channel/index.js +3 -3
- package/dist/commands/channel/index.js.map +1 -1
- package/dist/commands/channel/list.d.ts +1 -1
- package/dist/commands/channel/list.js +1 -1
- package/dist/commands/channel/rm.d.ts +1 -1
- package/dist/commands/channel/rm.js +1 -1
- package/dist/commands/channel/store/lock.d.ts +1 -1
- package/dist/commands/channel/store/lock.js +1 -1
- package/dist/commands/channel/store/paths.js +1 -1
- package/dist/commands/channel/store/paths.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +197 -91
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/uninstall.d.ts +4 -4
- package/dist/commands/uninstall.js +12 -12
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts +7 -2
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +161 -61
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upgrade.js +2 -2
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/commands/workflow.d.ts +4 -4
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +10 -9
- package/dist/commands/workflow.js.map +1 -1
- package/dist/configurators/cursor.d.ts +2 -2
- package/dist/configurators/cursor.js +4 -4
- package/dist/configurators/cursor.js.map +1 -1
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +4 -4
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/shared.d.ts +10 -10
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +32 -32
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/workflow.d.ts +6 -6
- package/dist/configurators/workflow.js +1 -1
- package/dist/constants/paths.d.ts +24 -24
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +16 -16
- package/dist/constants/paths.js.map +1 -1
- package/dist/migrations/manifests/0.2.10.json +374 -0
- package/dist/migrations/manifests/0.3.0.json +89 -0
- package/dist/migrations/manifests/0.3.1.json +32 -0
- package/dist/templates/common/bundled-skills/{trellis-cursor2plus-setup → cstl-cursor2plus-setup}/SKILL.md +15 -14
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/SKILL.md +75 -75
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/add-project-local-conventions.md +19 -19
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-agents.md +8 -8
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-context-loading.md +26 -26
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-hooks.md +9 -9
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-skills-or-commands.md +8 -8
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-spec-structure.md +17 -17
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-task-lifecycle.md +46 -46
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/change-workflow.md +18 -18
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/customize-local/overview.md +55 -55
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/context-injection.md +20 -20
- package/dist/templates/common/bundled-skills/cstl-meta/references/local-architecture/generated-files.md +83 -0
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/overview.md +15 -15
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/spec-system.md +12 -12
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/task-system.md +34 -34
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/workflow.md +8 -8
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/local-architecture/workspace-memory.md +19 -19
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/agents.md +12 -12
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/hooks-and-settings.md +7 -7
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/overview.md +9 -9
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/platform-map.md +7 -7
- package/dist/templates/common/bundled-skills/{trellis-meta → cstl-meta}/references/platform-files/skills-and-commands.md +19 -19
- package/dist/templates/common/bundled-skills/{trellis-micro-grill → cstl-micro-grill}/SKILL.md +62 -47
- package/dist/templates/common/bundled-skills/{trellis-skill-creator → cstl-skill-creator}/SKILL.md +44 -44
- package/dist/templates/common/bundled-skills/{trellis-skill-creator → cstl-skill-creator}/references/authoring-rules.md +97 -97
- package/dist/templates/common/bundled-skills/{trellis-skill-creator/references/trellis-skill-locations.md → cstl-skill-creator/references/cstl-skill-locations.md} +52 -52
- package/dist/templates/common/bundled-skills/{trellis-skill-creator → cstl-skill-creator}/references/review-checklist.md +47 -47
- package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/SKILL.md +6 -6
- package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/repository-analysis.md +1 -1
- package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/spec-task-planning.md +3 -3
- package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/spec-writing.md +1 -1
- package/dist/templates/common/commands/continue.md +24 -24
- package/dist/templates/common/commands/finish-work.md +5 -5
- package/dist/templates/common/commands/start.md +20 -20
- package/dist/templates/common/index.d.ts +1 -1
- package/dist/templates/common/index.d.ts.map +1 -1
- package/dist/templates/common/skills/before-dev.md +4 -4
- package/dist/templates/common/skills/brainstorm.md +188 -164
- package/dist/templates/common/skills/break-loop.md +3 -3
- package/dist/templates/common/skills/check.md +5 -5
- package/dist/templates/common/skills/update-spec.md +4 -4
- package/dist/templates/cursor/agents/{trellis-check.md → cstl-check.md} +14 -14
- package/dist/templates/cursor/agents/{trellis-implement.md → cstl-implement.md} +14 -14
- package/dist/templates/cursor/agents/{trellis-research.md → cstl-research.md} +11 -11
- package/dist/templates/cursor/commands/cursor2plus-setup.md +15 -15
- package/dist/templates/cursor/fixtures/expected-rules.d.ts +1 -1
- package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
- package/dist/templates/cursor/fixtures/expected-rules.js +2 -2
- package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
- package/dist/templates/cursor/rules/{trellis-subagent-dispatch.mdc → cstl-subagent-dispatch.mdc} +4 -4
- package/dist/templates/cursor/rules/{trellis-triage.mdc → cstl-triage.mdc} +3 -3
- package/dist/templates/cursor/rules/retrieval-routing.mdc +4 -4
- package/dist/templates/extract.d.ts +1 -1
- package/dist/templates/extract.js +1 -1
- package/dist/templates/markdown/agents.md +13 -13
- package/dist/templates/markdown/prompts/run-semantic-slice-12.md.txt +1 -1
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +634 -634
- package/dist/templates/markdown/spec/guides/cursor-context-injection-guide.md.txt +5 -5
- package/dist/templates/markdown/spec/guides/cursor-semantic-compliance.md.txt +7 -1
- package/dist/templates/markdown/spec/guides/cursor-subagent-policy.md.txt +393 -391
- package/dist/templates/markdown/spec/guides/durable-learning-decision-guide.md.txt +14 -14
- package/dist/templates/markdown/spec/guides/execution-strategy.md.txt +5 -5
- package/dist/templates/markdown/spec/guides/index.md.txt +3 -2
- package/dist/templates/markdown/spec/guides/retrieval-daily-guide.md.txt +10 -10
- package/dist/templates/markdown/workspace-index.md +3 -3
- package/dist/templates/markdown/worktree.yaml.txt +1 -1
- package/dist/templates/shared-hooks/index.d.ts +2 -2
- package/dist/templates/shared-hooks/index.js +2 -2
- package/dist/templates/shared-hooks/inject-retrieval-plan.py +3 -3
- package/dist/templates/shared-hooks/inject-shell-session-context.py +7 -7
- package/dist/templates/shared-hooks/inject-subagent-context.py +4 -4
- package/dist/templates/shared-hooks/inject-workflow-state.py +37 -37
- package/dist/templates/shared-hooks/research-end-retrieval-pack.py +2 -2
- package/dist/templates/shared-hooks/session-start.py +16 -16
- package/dist/templates/trellis/config/execution-strategy-rules.json +1 -1
- package/dist/templates/trellis/config.yaml +5 -25
- package/dist/templates/trellis/index.d.ts +2 -2
- package/dist/templates/trellis/index.js +2 -2
- package/dist/templates/trellis/local/README.md +15 -13
- package/dist/templates/trellis/local/patch_wpelc8.py +7 -7
- package/dist/templates/trellis/local/subagent-models.json.example +1 -1
- package/dist/templates/trellis/local/trellis-task-models.json.example +3 -3
- package/dist/templates/trellis/local/trellis-task-models.json5.example +5 -5
- package/dist/templates/trellis/local/trellis_task_models_config.py +6 -6
- package/dist/templates/trellis/scripts/add_session.py +20 -20
- package/dist/templates/trellis/scripts/common/active_task.py +2 -2
- package/dist/templates/trellis/scripts/common/artifact_search.py +587 -587
- package/dist/templates/trellis/scripts/common/cli_adapter.py +3 -3
- package/dist/templates/trellis/scripts/common/codebase_retrieval_router.py +6 -6
- package/dist/templates/trellis/scripts/common/config.py +3 -3
- package/dist/templates/trellis/scripts/common/developer.py +2 -2
- package/dist/templates/trellis/scripts/common/execution_strategy.py +1 -1
- package/dist/templates/trellis/scripts/common/packages_context.py +23 -23
- package/dist/templates/trellis/scripts/common/parent_orchestration.py +702 -702
- package/dist/templates/trellis/scripts/common/paths.py +107 -107
- package/dist/templates/trellis/scripts/common/project_file_stats.py +1 -1
- package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +1 -1
- package/dist/templates/trellis/scripts/common/safe_commit.py +31 -31
- package/dist/templates/trellis/scripts/common/session_context.py +1159 -1159
- package/dist/templates/trellis/scripts/common/session_memory.py +360 -360
- package/dist/templates/trellis/scripts/common/smart_search_evidence.py +514 -514
- package/dist/templates/trellis/scripts/common/smart_search_resolve.py +1 -1
- package/dist/templates/trellis/scripts/common/subagent_dispatch.py +7 -7
- package/dist/templates/trellis/scripts/common/task_context.py +1 -1
- package/dist/templates/trellis/scripts/common/task_dashboard.py +140 -140
- package/dist/templates/trellis/scripts/common/task_gates.py +2056 -2034
- package/dist/templates/trellis/scripts/common/task_store.py +1594 -1594
- package/dist/templates/trellis/scripts/common/task_utils.py +3 -3
- package/dist/templates/trellis/scripts/common/tasks.py +1 -1
- package/dist/templates/trellis/scripts/common/trellis_config.py +3 -3
- package/dist/templates/trellis/scripts/common/workflow_phase.py +1 -1
- package/dist/templates/trellis/scripts/cursor_retrieval_probe.py +3 -3
- package/dist/templates/trellis/scripts/cursor_retrieval_probe_prompt.md +11 -11
- package/dist/templates/trellis/scripts/hooks/linear_sync.py +8 -8
- package/dist/templates/trellis/scripts/init_developer.py +2 -2
- package/dist/templates/trellis/scripts/retrieval_probe_matrix_template.json +4 -4
- package/dist/templates/trellis/scripts/route_codebase_retrieval.py +1 -1
- package/dist/templates/trellis/scripts/task.py +918 -918
- package/dist/templates/trellis/tasks/templates/release-readiness/implement.md +2 -2
- package/dist/templates/trellis/workflow.md +805 -805
- package/dist/types/ai-tools.d.ts +1 -1
- package/dist/types/ai-tools.d.ts.map +1 -1
- package/dist/types/ai-tools.js +1 -1
- package/dist/types/ai-tools.js.map +1 -1
- package/dist/types/migration.d.ts +1 -1
- package/dist/types/migration.d.ts.map +1 -1
- package/dist/utils/agents-md.d.ts +37 -0
- package/dist/utils/agents-md.d.ts.map +1 -0
- package/dist/utils/agents-md.js +82 -0
- package/dist/utils/agents-md.js.map +1 -0
- package/dist/utils/codebase-retrieval-router.js +5 -5
- package/dist/utils/codebase-retrieval-router.js.map +1 -1
- package/dist/utils/manifest-prune.d.ts +2 -2
- package/dist/utils/manifest-prune.js +4 -4
- package/dist/utils/manifest-prune.js.map +1 -1
- package/dist/utils/mirror-check.d.ts +3 -1
- package/dist/utils/mirror-check.d.ts.map +1 -1
- package/dist/utils/mirror-check.js +22 -11
- package/dist/utils/mirror-check.js.map +1 -1
- package/dist/utils/project-capabilities.d.ts +14 -3
- package/dist/utils/project-capabilities.d.ts.map +1 -1
- package/dist/utils/project-capabilities.js +127 -17
- package/dist/utils/project-capabilities.js.map +1 -1
- package/dist/utils/readiness.d.ts +10 -0
- package/dist/utils/readiness.d.ts.map +1 -1
- package/dist/utils/readiness.js +6 -3
- package/dist/utils/readiness.js.map +1 -1
- package/dist/utils/retrieval-agent-instructions.js +1 -1
- package/dist/utils/retrieval-agent-instructions.js.map +1 -1
- package/dist/utils/retrieval-execution-telemetry.js +1 -1
- package/dist/utils/retrieval-execution-telemetry.js.map +1 -1
- package/dist/utils/template-fetcher.js +1 -1
- package/dist/utils/template-fetcher.js.map +1 -1
- package/dist/utils/template-hash.d.ts +2 -2
- package/dist/utils/template-hash.d.ts.map +1 -1
- package/dist/utils/template-hash.js +12 -10
- package/dist/utils/template-hash.js.map +1 -1
- package/dist/utils/workflow-dir.d.ts +13 -0
- package/dist/utils/workflow-dir.d.ts.map +1 -0
- package/dist/utils/workflow-dir.js +35 -0
- package/dist/utils/workflow-dir.js.map +1 -0
- package/dist/utils/workflow-ownership.d.ts +36 -0
- package/dist/utils/workflow-ownership.d.ts.map +1 -0
- package/dist/utils/workflow-ownership.js +137 -0
- package/dist/utils/workflow-ownership.js.map +1 -0
- package/dist/utils/workflow-resolver.d.ts +1 -1
- package/dist/utils/workflow-resolver.js +1 -1
- package/package.json +3 -4
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +0 -83
- /package/bin/{trellis.js → cstl.js} +0 -0
- /package/dist/templates/common/bundled-skills/{trellis-spec-bootstrap → cstl-spec-bootstrap}/references/mcp-setup.md +0 -0
package/dist/commands/init.js
CHANGED
|
@@ -12,7 +12,8 @@ import { AI_TOOLS } from "../types/ai-tools.js";
|
|
|
12
12
|
import { DIR_NAMES, FILE_NAMES, PATHS } from "../constants/paths.js";
|
|
13
13
|
import { VERSION } from "../constants/version.js";
|
|
14
14
|
import { agentsMdContent } from "../templates/markdown/index.js";
|
|
15
|
-
import { setWriteMode, startRecordingWrites, stopRecordingWrites, writeFile, } from "../utils/file-writer.js";
|
|
15
|
+
import { setWriteMode, getWriteMode, startRecordingWrites, stopRecordingWrites, writeFile, } from "../utils/file-writer.js";
|
|
16
|
+
import { insertCstlManagedBlock } from "../utils/agents-md.js";
|
|
16
17
|
import { emptyTaskJson } from "../utils/task-json.js";
|
|
17
18
|
import { detectProjectType, detectMonorepo, sanitizePkgName, } from "../utils/project-detector.js";
|
|
18
19
|
import { initializeHashes, removeHash } from "../utils/template-hash.js";
|
|
@@ -21,7 +22,7 @@ import { isCwdHomedir, homedirGuardMessage, homedirBypassEnabled, } from "../uti
|
|
|
21
22
|
import { fetchTemplateIndex, probeRegistryIndex, downloadTemplateById, downloadRegistryDirect, parseRegistrySource, TIMEOUTS, TEMPLATE_INDEX_URL, } from "../utils/template-fetcher.js";
|
|
22
23
|
import { setupProxy, maskProxyUrl } from "../utils/proxy.js";
|
|
23
24
|
import { checkProjectCapabilityReadiness, checkSmartSearchReadiness, } from "../utils/readiness.js";
|
|
24
|
-
import { getProjectCapabilityChoices, parseProjectCapabilities, writeProjectCapabilityFiles, } from "../utils/project-capabilities.js";
|
|
25
|
+
import { getProjectCapability, getProjectCapabilityChoices, loadProjectCapabilities, parseProjectCapabilities, writeProjectCapabilityFiles, } from "../utils/project-capabilities.js";
|
|
25
26
|
import { assertCursorRulesValid } from "../utils/validate-rules.js";
|
|
26
27
|
const MIN_PYTHON_MAJOR = 3;
|
|
27
28
|
const MIN_PYTHON_MINOR = 9;
|
|
@@ -78,7 +79,7 @@ export function requireSupportedPython(command) {
|
|
|
78
79
|
* Windows: `python` is the usual python.org installer choice, but Microsoft
|
|
79
80
|
* Store ships `python3`, and the `py` launcher is `py -3`. We try all three
|
|
80
81
|
* before giving up — fixes #236 where users with only `python3` (not
|
|
81
|
-
* `python`) had `
|
|
82
|
+
* `python`) had `cstl init` fail outright.
|
|
82
83
|
*
|
|
83
84
|
* Non-Windows: `python3` is canonical; `python` is a fallback for systems
|
|
84
85
|
* where Python 3 is the only Python and is named `python` (some Arch
|
|
@@ -176,10 +177,10 @@ function logPythonAdaptationNotice(command) {
|
|
|
176
177
|
}
|
|
177
178
|
function logCursor2plusSetupHint() {
|
|
178
179
|
console.log("");
|
|
179
|
-
console.log(chalk.cyan("🔧 Cursor++ BYOK: 在 Cursor Agent 中运行 skill
|
|
180
|
-
console.log(chalk.gray(" 与大模型交互选择各 Task 角色的 primary/fallback 模型,并应用
|
|
181
|
-
console.log(chalk.gray(" 本地包: .
|
|
182
|
-
console.log(chalk.gray(" 使用官方 Cursor API(非 Cursor++)可安全忽略 `.
|
|
180
|
+
console.log(chalk.cyan("🔧 Cursor++ BYOK: 在 Cursor Agent 中运行 skill cstl-cursor2plus-setup"));
|
|
181
|
+
console.log(chalk.gray(" 与大模型交互选择各 Task 角色的 primary/fallback 模型,并应用 Method 2.5 patch(升级 Cursor/Cursor++ 后先跑 patch_wpelc8.py --check-compat)。"));
|
|
182
|
+
console.log(chalk.gray(" 本地包: .cstl/local/cursor2plus/ · 示例: trellis-task-models.json5.example"));
|
|
183
|
+
console.log(chalk.gray(" 使用官方 Cursor API(非 Cursor++)可安全忽略 `.cstl/local/cursor2plus/`。"));
|
|
183
184
|
console.log("");
|
|
184
185
|
}
|
|
185
186
|
// =============================================================================
|
|
@@ -248,19 +249,50 @@ function getBootstrapChecklistItems(projectType, packages) {
|
|
|
248
249
|
"Add code examples",
|
|
249
250
|
];
|
|
250
251
|
}
|
|
252
|
+
function renderCapabilityReadinessSection(selectedCapabilities) {
|
|
253
|
+
if (selectedCapabilities.length === 0) {
|
|
254
|
+
return "";
|
|
255
|
+
}
|
|
256
|
+
const checklist = selectedCapabilities
|
|
257
|
+
.map((id) => {
|
|
258
|
+
const capability = getProjectCapability(id);
|
|
259
|
+
return `- [ ] \`${capability.id}\` — ${capability.title}. Verify the generated MCP/config path is usable before claiming it in task evidence.`;
|
|
260
|
+
})
|
|
261
|
+
.join("\n");
|
|
262
|
+
return `
|
|
263
|
+
## Capability readiness (required before archive)
|
|
264
|
+
|
|
265
|
+
Init selected optional project capabilities for this repo. Treat them as
|
|
266
|
+
\`pending\` until you verify they work in this checkout.
|
|
267
|
+
|
|
268
|
+
${checklist}
|
|
269
|
+
|
|
270
|
+
- Read \`.cstl/capabilities.json\` / \`.cstl/capabilities.md\` and keep the
|
|
271
|
+
readiness state honest: \`pending\`, \`ready\`, or \`failed\`.
|
|
272
|
+
- For \`codebase-retrieval\`, verify \`.codegraph/\` exists (or initialize it)
|
|
273
|
+
and confirm the MCP path is usable. After the first index, CodeGraph's file
|
|
274
|
+
watcher auto-syncs later edits; you do not need to re-run full indexing for
|
|
275
|
+
every code change.
|
|
276
|
+
- If a capability cannot be made ready, record the failure and fallback path in
|
|
277
|
+
\`verify.md\` before archiving bootstrap.
|
|
278
|
+
- Validation entrypoint: \`cstl capability-smoke --write-status\`
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
`;
|
|
282
|
+
}
|
|
251
283
|
function getBootstrapRelatedFiles(projectType, packages) {
|
|
252
284
|
if (packages && packages.length > 0) {
|
|
253
|
-
return packages.map((pkg) => `.
|
|
285
|
+
return packages.map((pkg) => `.cstl/spec/${sanitizePkgName(pkg.name)}/`);
|
|
254
286
|
}
|
|
255
287
|
if (projectType === "frontend") {
|
|
256
|
-
return [".
|
|
288
|
+
return [".cstl/spec/frontend/"];
|
|
257
289
|
}
|
|
258
290
|
if (projectType === "backend") {
|
|
259
|
-
return [".
|
|
291
|
+
return [".cstl/spec/backend/"];
|
|
260
292
|
}
|
|
261
|
-
return [".
|
|
293
|
+
return [".cstl/spec/backend/", ".cstl/spec/frontend/"];
|
|
262
294
|
}
|
|
263
|
-
function getBootstrapPrdContent(projectType, pythonCmd, packages) {
|
|
295
|
+
function getBootstrapPrdContent(projectType, pythonCmd, selectedCapabilities, packages) {
|
|
264
296
|
const checklistItems = getBootstrapChecklistItems(projectType, packages);
|
|
265
297
|
const checklistMarkdown = checklistItems
|
|
266
298
|
.map((item) => `- [ ] ${item}`)
|
|
@@ -269,14 +301,14 @@ function getBootstrapPrdContent(projectType, pythonCmd, packages) {
|
|
|
269
301
|
|
|
270
302
|
**You (the AI) are running this task. The developer does not read this file.**
|
|
271
303
|
|
|
272
|
-
The developer just ran \`
|
|
273
|
-
\`.
|
|
274
|
-
exists under \`.
|
|
304
|
+
The developer just ran \`cstl init\` on this project for the first time.
|
|
305
|
+
\`.cstl/\` now exists with empty spec scaffolding, and this bootstrap task
|
|
306
|
+
exists under \`.cstl/tasks/\`. When they want to work on it, they should start
|
|
275
307
|
this task from a session that provides Trellis session identity.
|
|
276
308
|
|
|
277
|
-
**Your job**: help them populate \`.
|
|
309
|
+
**Your job**: help them populate \`.cstl/spec/\` with the team's real
|
|
278
310
|
coding conventions. Every future AI session — this project's
|
|
279
|
-
\`
|
|
311
|
+
\`cstl-implement\` and \`cstl-check\` sub-agents — auto-loads spec files
|
|
280
312
|
listed in per-task jsonl manifests. Empty spec = sub-agents write generic
|
|
281
313
|
code. Real spec = sub-agents match the team's actual patterns.
|
|
282
314
|
|
|
@@ -292,6 +324,8 @@ ${checklistMarkdown}
|
|
|
292
324
|
|
|
293
325
|
---
|
|
294
326
|
|
|
327
|
+
${renderCapabilityReadinessSection(selectedCapabilities)}
|
|
328
|
+
|
|
295
329
|
## Spec files to populate
|
|
296
330
|
`;
|
|
297
331
|
const backendSection = `
|
|
@@ -300,11 +334,11 @@ ${checklistMarkdown}
|
|
|
300
334
|
|
|
301
335
|
| File | What to document |
|
|
302
336
|
|------|------------------|
|
|
303
|
-
| \`.
|
|
304
|
-
| \`.
|
|
305
|
-
| \`.
|
|
306
|
-
| \`.
|
|
307
|
-
| \`.
|
|
337
|
+
| \`.cstl/spec/backend/directory-structure.md\` | Where different file types go (routes, services, utils) |
|
|
338
|
+
| \`.cstl/spec/backend/database-guidelines.md\` | ORM, migrations, query patterns, naming conventions |
|
|
339
|
+
| \`.cstl/spec/backend/error-handling.md\` | How errors are caught, logged, and returned |
|
|
340
|
+
| \`.cstl/spec/backend/logging-guidelines.md\` | Log levels, format, what to log |
|
|
341
|
+
| \`.cstl/spec/backend/quality-guidelines.md\` | Code review standards, testing requirements |
|
|
308
342
|
`;
|
|
309
343
|
const frontendSection = `
|
|
310
344
|
|
|
@@ -312,18 +346,18 @@ ${checklistMarkdown}
|
|
|
312
346
|
|
|
313
347
|
| File | What to document |
|
|
314
348
|
|------|------------------|
|
|
315
|
-
| \`.
|
|
316
|
-
| \`.
|
|
317
|
-
| \`.
|
|
318
|
-
| \`.
|
|
319
|
-
| \`.
|
|
320
|
-
| \`.
|
|
349
|
+
| \`.cstl/spec/frontend/directory-structure.md\` | Component/page/hook organization |
|
|
350
|
+
| \`.cstl/spec/frontend/component-guidelines.md\` | Component patterns, props conventions |
|
|
351
|
+
| \`.cstl/spec/frontend/hook-guidelines.md\` | Custom hook naming, patterns |
|
|
352
|
+
| \`.cstl/spec/frontend/state-management.md\` | State library, patterns, what goes where |
|
|
353
|
+
| \`.cstl/spec/frontend/type-safety.md\` | TypeScript conventions, type organization |
|
|
354
|
+
| \`.cstl/spec/frontend/quality-guidelines.md\` | Linting, testing, accessibility |
|
|
321
355
|
`;
|
|
322
356
|
const footer = `
|
|
323
357
|
|
|
324
358
|
### Thinking guides (already populated)
|
|
325
359
|
|
|
326
|
-
\`.
|
|
360
|
+
\`.cstl/spec/guides/\` contains general thinking guides pre-filled with
|
|
327
361
|
best practices. Customize only if something clearly doesn't fit this project.
|
|
328
362
|
|
|
329
363
|
---
|
|
@@ -333,7 +367,7 @@ best practices. Customize only if something clearly doesn't fit this project.
|
|
|
333
367
|
### Step 1: Import from existing convention files first (preferred)
|
|
334
368
|
|
|
335
369
|
Search the repo for existing convention docs. If any exist, read them and
|
|
336
|
-
extract the relevant rules into the matching \`.
|
|
370
|
+
extract the relevant rules into the matching \`.cstl/spec/\` files —
|
|
337
371
|
usually much faster than documenting from scratch.
|
|
338
372
|
|
|
339
373
|
| File / Directory | Notes |
|
|
@@ -364,14 +398,14 @@ is a separate conversation, not a bootstrap concern.
|
|
|
364
398
|
|
|
365
399
|
## Quick explainer of the runtime (share when they ask "why do we need spec at all")
|
|
366
400
|
|
|
367
|
-
- Every AI coding task spawns two sub-agents: \`
|
|
368
|
-
code) and \`
|
|
401
|
+
- Every AI coding task spawns two sub-agents: \`cstl-implement\` (writes
|
|
402
|
+
code) and \`cstl-check\` (verifies quality).
|
|
369
403
|
- Each task has \`implement.jsonl\` / \`check.jsonl\` manifests listing which
|
|
370
404
|
spec files to load.
|
|
371
405
|
- The platform hook auto-injects those spec files + the task's \`prd.md\`
|
|
372
406
|
into every sub-agent prompt, so the sub-agent codes/reviews per team
|
|
373
407
|
conventions without anyone pasting them manually.
|
|
374
|
-
- Source of truth: \`.
|
|
408
|
+
- Source of truth: \`.cstl/spec/\`. That's why filling it well now pays
|
|
375
409
|
off forever.
|
|
376
410
|
|
|
377
411
|
---
|
|
@@ -382,7 +416,7 @@ When the developer confirms the checklist items above are done with real
|
|
|
382
416
|
examples (not placeholders), guide them to run:
|
|
383
417
|
|
|
384
418
|
\`\`\`bash
|
|
385
|
-
${pythonCmd} ./.
|
|
419
|
+
${pythonCmd} ./.cstl/scripts/task.py archive 00-bootstrap-guidelines
|
|
386
420
|
\`\`\`
|
|
387
421
|
|
|
388
422
|
After archive, every new developer who joins this project will get a
|
|
@@ -406,10 +440,10 @@ etc.) I can pull from, or should I scan the codebase from scratch?"
|
|
|
406
440
|
const specName = sanitizePkgName(pkg.name);
|
|
407
441
|
content += `\n### Package: ${pkg.name} (\`spec/${specName}/\`)\n`;
|
|
408
442
|
if (pkgType !== "frontend") {
|
|
409
|
-
content += `\n- Backend guidelines: \`.
|
|
443
|
+
content += `\n- Backend guidelines: \`.cstl/spec/${specName}/backend/\`\n`;
|
|
410
444
|
}
|
|
411
445
|
if (pkgType !== "backend") {
|
|
412
|
-
content += `\n- Frontend guidelines: \`.
|
|
446
|
+
content += `\n- Frontend guidelines: \`.cstl/spec/${specName}/frontend/\`\n`;
|
|
413
447
|
}
|
|
414
448
|
}
|
|
415
449
|
}
|
|
@@ -446,15 +480,15 @@ function getBootstrapTaskJson(developer, projectType, packages) {
|
|
|
446
480
|
assignee: developer,
|
|
447
481
|
createdAt: today,
|
|
448
482
|
relatedFiles,
|
|
449
|
-
notes: `First-time setup task created by
|
|
483
|
+
notes: `First-time setup task created by cstl init (${projectType} project)`,
|
|
450
484
|
});
|
|
451
485
|
}
|
|
452
486
|
/**
|
|
453
487
|
* Create bootstrap task for first-time setup
|
|
454
488
|
*/
|
|
455
|
-
function createBootstrapTask(cwd, developer, pythonCmd, projectType, packages) {
|
|
489
|
+
function createBootstrapTask(cwd, developer, pythonCmd, projectType, selectedCapabilities, packages) {
|
|
456
490
|
const taskJson = getBootstrapTaskJson(developer, projectType, packages);
|
|
457
|
-
const prdContent = getBootstrapPrdContent(projectType, pythonCmd, packages);
|
|
491
|
+
const prdContent = getBootstrapPrdContent(projectType, pythonCmd, selectedCapabilities, packages);
|
|
458
492
|
return writeTaskSkeleton(cwd, BOOTSTRAP_TASK_NAME, taskJson, prdContent);
|
|
459
493
|
}
|
|
460
494
|
// =============================================================================
|
|
@@ -478,22 +512,44 @@ function getJoinerTaskJson(developer, taskName) {
|
|
|
478
512
|
creator: developer,
|
|
479
513
|
assignee: developer,
|
|
480
514
|
createdAt: today,
|
|
481
|
-
notes: "Generated by
|
|
515
|
+
notes: "Generated by cstl init for a new developer joining an existing Trellis project",
|
|
482
516
|
});
|
|
483
517
|
}
|
|
484
518
|
/**
|
|
485
519
|
* PRD content for joiner onboarding. Kept concise (~80 lines) — deeper
|
|
486
520
|
* guidance lives in skills and docs.
|
|
487
521
|
*/
|
|
488
|
-
function getJoinerPrdContent(developer, pythonCmd) {
|
|
522
|
+
function getJoinerPrdContent(developer, pythonCmd, selectedCapabilities) {
|
|
489
523
|
const slug = slugifyDeveloperName(developer);
|
|
524
|
+
const selectedCapabilityChecklist = selectedCapabilities
|
|
525
|
+
.map((id) => {
|
|
526
|
+
const capability = getProjectCapability(id);
|
|
527
|
+
return `- \`${capability.id}\` — re-check readiness in this clone before claiming it is available.`;
|
|
528
|
+
})
|
|
529
|
+
.join("\n");
|
|
530
|
+
let capabilitySection = "";
|
|
531
|
+
if (selectedCapabilities.length > 0) {
|
|
532
|
+
capabilitySection = `
|
|
533
|
+
### 5. Re-verify selected project capabilities
|
|
534
|
+
|
|
535
|
+
This repo has capability selections recorded in \`.cstl/capabilities.json\`.
|
|
536
|
+
Before they rely on MCP-backed behavior, remind them to check the selected set:
|
|
537
|
+
|
|
538
|
+
${selectedCapabilityChecklist}
|
|
539
|
+
|
|
540
|
+
- If a capability is not \`ready\`, have them re-run the local verification path
|
|
541
|
+
instead of assuming the previous machine's setup carries over.
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
`;
|
|
545
|
+
}
|
|
490
546
|
return `# Joiner Onboarding Task
|
|
491
547
|
|
|
492
548
|
**You (the AI) are running this task. The developer does not read this file.**
|
|
493
549
|
|
|
494
|
-
\`${developer}\` just ran \`
|
|
550
|
+
\`${developer}\` just ran \`cstl init\` on a fresh clone, saw "Developer
|
|
495
551
|
initialized", and will now start asking you questions in chat. This joiner task
|
|
496
|
-
exists under \`.
|
|
552
|
+
exists under \`.cstl/tasks/\`; when they want to work on it, they should
|
|
497
553
|
select it from a session that provides Trellis session identity.
|
|
498
554
|
|
|
499
555
|
Your job is to orient them to Trellis. Don't dump all of this at them — open
|
|
@@ -511,13 +567,13 @@ agents consistent with project-specific conventions instead of writing generic
|
|
|
511
567
|
code every session.
|
|
512
568
|
|
|
513
569
|
- **Three phases**: Plan (brainstorm → \`prd.md\`) → Execute (code + check) →
|
|
514
|
-
Finish (capture + wrap). Full reference: \`.
|
|
570
|
+
Finish (capture + wrap). Full reference: \`.cstl/workflow.md\`.
|
|
515
571
|
- **Task lifecycle**: planning → in_progress → done → archive, under
|
|
516
|
-
\`.
|
|
572
|
+
\`.cstl/tasks/\`.
|
|
517
573
|
- **Core slash commands**:
|
|
518
|
-
- \`/
|
|
519
|
-
- \`/
|
|
520
|
-
- \`/
|
|
574
|
+
- \`/cstl:continue\` — continue the current live session's selected task
|
|
575
|
+
- \`/cstl:finish-work\` — wrap up a finished task
|
|
576
|
+
- \`/cstl:start\` — framework/dashboard entry (not needed here; the
|
|
521
577
|
SessionStart hook does its job automatically)
|
|
522
578
|
|
|
523
579
|
### 2. Runtime mechanics (explain when they ask "how does it know what to do")
|
|
@@ -527,28 +583,28 @@ code every session.
|
|
|
527
583
|
conversation at every session start.
|
|
528
584
|
- **\`<workflow-state>\` tag** is auto-injected with every user message,
|
|
529
585
|
carrying the selected task + phase hint.
|
|
530
|
-
- **\`/
|
|
531
|
-
activity, and routes to the right skill (\`
|
|
532
|
-
\`
|
|
533
|
-
- **\`
|
|
586
|
+
- **\`/cstl:continue\`** loads the Phase Index, reads \`prd.md\` + recent
|
|
587
|
+
activity, and routes to the right skill (\`cstl-brainstorm\` for planning,
|
|
588
|
+
\`cstl-implement\` for coding, \`cstl-check\` for verification).
|
|
589
|
+
- **\`cstl-implement\` sub-agent** is spawned when code needs to be written.
|
|
534
590
|
The platform hook reads \`{TASK_DIR}/implement.jsonl\` and auto-injects those
|
|
535
591
|
spec files + \`prd.md\` into the sub-agent's prompt so it codes per project
|
|
536
592
|
conventions.
|
|
537
|
-
- **\`
|
|
593
|
+
- **\`cstl-check\` sub-agent** follows the same pattern with \`check.jsonl\`
|
|
538
594
|
— reviews changes against specs, auto-fixes issues, runs lint/typecheck.
|
|
539
595
|
|
|
540
596
|
File layout (mention when they ask "where does what live"):
|
|
541
|
-
- \`.
|
|
542
|
-
- \`.
|
|
543
|
-
- \`.
|
|
544
|
-
- \`.
|
|
597
|
+
- \`.cstl/.runtime/sessions/<session>.json\` — live-session selected-task state, gitignored
|
|
598
|
+
- \`.cstl/tasks/<task>/{implement,check}.jsonl\` — per-task context manifests
|
|
599
|
+
- \`.cstl/spec/\` — project-wide conventions (source of truth)
|
|
600
|
+
- \`.cstl/workspace/${developer}/journal-*.md\` — their session log,
|
|
545
601
|
rotated at ~2000 lines
|
|
546
602
|
|
|
547
603
|
### 3. This project's actual conventions
|
|
548
604
|
|
|
549
|
-
- Summarize \`.
|
|
605
|
+
- Summarize \`.cstl/spec/\` for them — what coding conventions this
|
|
550
606
|
specific team enforces.
|
|
551
|
-
- Point at the last 5 entries in \`.
|
|
607
|
+
- Point at the last 5 entries in \`.cstl/tasks/archive/\` as a rhythm
|
|
552
608
|
example of how people actually work here. **If archive is empty** (the
|
|
553
609
|
project just started), skip this — don't invent examples.
|
|
554
610
|
- Not your job in this onboarding to teach them the business code itself —
|
|
@@ -556,20 +612,22 @@ File layout (mention when they ask "where does what live"):
|
|
|
556
612
|
|
|
557
613
|
### 4. Their assigned work
|
|
558
614
|
|
|
559
|
-
- Check if \`.
|
|
615
|
+
- Check if \`.cstl/workspace/${developer}/\` already exists — if yes, it's
|
|
560
616
|
their journal from another machine and worth mentioning.
|
|
561
|
-
- Run \`${pythonCmd} ./.
|
|
617
|
+
- Run \`${pythonCmd} ./.cstl/scripts/task.py list --assignee ${developer}\` to
|
|
562
618
|
show tasks assigned to them. (Quote the name if it contains spaces.)
|
|
563
619
|
- Remind them that the "My Tasks" section appears in the SessionStart context
|
|
564
620
|
on every new session.
|
|
565
621
|
|
|
566
622
|
---
|
|
567
623
|
|
|
624
|
+
${capabilitySection}
|
|
625
|
+
|
|
568
626
|
## Optional: walk through a small task end-to-end
|
|
569
627
|
|
|
570
628
|
If they want to practice before touching real work, offer to pick a tiny
|
|
571
|
-
P3 task or a typo fix and run the full cycle together: \`/
|
|
572
|
-
→ you implement via sub-agents → \`/
|
|
629
|
+
P3 task or a typo fix and run the full cycle together: \`/cstl:continue\`
|
|
630
|
+
→ you implement via sub-agents → \`/cstl:finish-work\`.
|
|
573
631
|
|
|
574
632
|
---
|
|
575
633
|
|
|
@@ -579,14 +637,14 @@ When they feel oriented (or after you've covered the four topics with
|
|
|
579
637
|
reasonable back-and-forth), guide them to run:
|
|
580
638
|
|
|
581
639
|
\`\`\`bash
|
|
582
|
-
${pythonCmd} ./.
|
|
640
|
+
${pythonCmd} ./.cstl/scripts/task.py archive 00-join-${slug}
|
|
583
641
|
\`\`\`
|
|
584
642
|
|
|
585
643
|
---
|
|
586
644
|
|
|
587
645
|
## Suggested opening line
|
|
588
646
|
|
|
589
|
-
"Welcome! Your \`
|
|
647
|
+
"Welcome! Your \`cstl init\` set me up to onboard you to this project. I
|
|
590
648
|
can walk you through the workflow, show you the runtime mechanics under the
|
|
591
649
|
hood, summarize the team's spec, or jump to what you're already curious about
|
|
592
650
|
— which would you prefer?"
|
|
@@ -601,11 +659,11 @@ function createJoinerOnboardingTask(cwd, developer, pythonCmd) {
|
|
|
601
659
|
const slug = slugifyDeveloperName(developer);
|
|
602
660
|
const taskName = `00-join-${slug}`;
|
|
603
661
|
const taskJson = getJoinerTaskJson(developer, taskName);
|
|
604
|
-
const prdContent = getJoinerPrdContent(developer, pythonCmd);
|
|
662
|
+
const prdContent = getJoinerPrdContent(developer, pythonCmd, loadProjectCapabilities(cwd));
|
|
605
663
|
return writeTaskSkeleton(cwd, taskName, taskJson, prdContent);
|
|
606
664
|
}
|
|
607
665
|
/**
|
|
608
|
-
* Handle re-init when .
|
|
666
|
+
* Handle re-init when .cstl/ already exists.
|
|
609
667
|
* Returns true if handled (caller should return), false if user chose full re-init.
|
|
610
668
|
*/
|
|
611
669
|
async function handleReinit(cwd, options, developerName, pythonCmd) {
|
|
@@ -734,7 +792,7 @@ async function handleReinit(cwd, options, developerName, pythonCmd) {
|
|
|
734
792
|
}
|
|
735
793
|
catch {
|
|
736
794
|
console.log(chalk.yellow("⚠ Could not initialize developer. Run manually:"));
|
|
737
|
-
console.log(chalk.gray(` ${pythonCmd} .
|
|
795
|
+
console.log(chalk.gray(` ${pythonCmd} .cstl/scripts/init_developer.py ${devName}`));
|
|
738
796
|
}
|
|
739
797
|
// Create joiner onboarding task for fresh checkouts (no prior .developer).
|
|
740
798
|
// Runs outside the init_developer try/catch so failures surface as warnings.
|
|
@@ -789,7 +847,7 @@ function writeMonorepoConfig(cwd, packages) {
|
|
|
789
847
|
fs.writeFileSync(configPath, content.trimEnd() + "\n" + lines.join("\n") + "\n", "utf-8");
|
|
790
848
|
}
|
|
791
849
|
async function checkSmartSearchReadinessForInit(options) {
|
|
792
|
-
const skipReadinessCommand = "
|
|
850
|
+
const skipReadinessCommand = "cstl init --skip-readiness";
|
|
793
851
|
try {
|
|
794
852
|
checkSmartSearchReadiness({
|
|
795
853
|
skipReadiness: options.skipReadiness,
|
|
@@ -845,7 +903,7 @@ async function checkSmartSearchReadinessForInit(options) {
|
|
|
845
903
|
}
|
|
846
904
|
}
|
|
847
905
|
async function checkProjectCapabilityReadinessForInit(options) {
|
|
848
|
-
const skipReadinessCommand = "
|
|
906
|
+
const skipReadinessCommand = "cstl init --skip-readiness";
|
|
849
907
|
try {
|
|
850
908
|
checkProjectCapabilityReadiness({
|
|
851
909
|
cwd: options.cwd,
|
|
@@ -893,7 +951,7 @@ async function checkProjectCapabilityReadinessForInit(options) {
|
|
|
893
951
|
export async function init(options) {
|
|
894
952
|
// Refuse to run in $HOME — running here would scoop platform runtime data
|
|
895
953
|
// (Claude/Codex/OpenCode session histories etc.) into the trellis hash
|
|
896
|
-
// manifest, and a subsequent `
|
|
954
|
+
// manifest, and a subsequent `cstl uninstall` would wipe it.
|
|
897
955
|
if (isCwdHomedir() && !homedirBypassEnabled()) {
|
|
898
956
|
console.error(chalk.red(homedirGuardMessage("init")));
|
|
899
957
|
process.exit(1);
|
|
@@ -902,8 +960,19 @@ export async function init(options) {
|
|
|
902
960
|
const isFirstInit = !fs.existsSync(path.join(cwd, DIR_NAMES.WORKFLOW));
|
|
903
961
|
// Captured here (before createWorkflowStructure + init_developer run) so
|
|
904
962
|
// the three-branch dispatch at the bottom can tell "fresh clone joiner"
|
|
905
|
-
// (.
|
|
963
|
+
// (.cstl/ exists, .developer missing) apart from "creator first init".
|
|
906
964
|
const hadDeveloperFileAtStart = fs.existsSync(path.join(cwd, DIR_NAMES.WORKFLOW, FILE_NAMES.DEVELOPER));
|
|
965
|
+
// Coexistence mode: an upstream mindfold-ai/Trellis `.trellis/` tree exists
|
|
966
|
+
// but cursor-trellis has no `.cstl/` yet. The user is adding cursor-trellis
|
|
967
|
+
// on Cursor alongside upstream Trellis (scenario 2). cursor-trellis owns
|
|
968
|
+
// `.cursor/` and `.cstl/`; it must NOT touch `.trellis/` and must preserve
|
|
969
|
+
// an existing `<!-- TRELLIS:START -->` block in AGENTS.md.
|
|
970
|
+
const coexistenceMode = isFirstInit && fs.existsSync(path.join(cwd, ".trellis"));
|
|
971
|
+
if (coexistenceMode) {
|
|
972
|
+
console.log(chalk.cyan("\n Detected upstream `.trellis/` — coexistence mode: cursor-trellis will use `.cstl/`"));
|
|
973
|
+
console.log(chalk.gray(" alongside `.trellis/` and take over `.cursor/`. `.trellis/` will not be touched.\n"));
|
|
974
|
+
console.log(chalk.gray(" Do NOT run `cstl update --migrate` here — that would rename the upstream `.trellis/`.\n"));
|
|
975
|
+
}
|
|
907
976
|
// Generate ASCII art banner dynamically using FIGlet "Rebel" font
|
|
908
977
|
const banner = figlet.textSync("Trellis", { font: "Rebel" });
|
|
909
978
|
console.log(chalk.cyan(`\n${banner.trimEnd()}`));
|
|
@@ -952,9 +1021,9 @@ export async function init(options) {
|
|
|
952
1021
|
}
|
|
953
1022
|
const { command: pythonCmd } = resolveSupportedPython();
|
|
954
1023
|
// ==========================================================================
|
|
955
|
-
// Re-init fast path: skip full flow when .
|
|
1024
|
+
// Re-init fast path: skip full flow when .cstl/ already exists
|
|
956
1025
|
// ==========================================================================
|
|
957
|
-
// Aborted-init recovery (issue #204): if .
|
|
1026
|
+
// Aborted-init recovery (issue #204): if .cstl/ exists but tasks/ is
|
|
958
1027
|
// empty, the previous init never reached bootstrap creation. Fall through
|
|
959
1028
|
// to the full flow so the main-dispatch tasksEmpty fallback fires —
|
|
960
1029
|
// handleReinit's joiner branch would otherwise mis-route the recovery.
|
|
@@ -1022,7 +1091,7 @@ export async function init(options) {
|
|
|
1022
1091
|
console.log(chalk.gray(" ✗ .gitmodules"));
|
|
1023
1092
|
console.log(chalk.gray(" ✗ sibling .git directories (need ≥ 2)"));
|
|
1024
1093
|
console.log("");
|
|
1025
|
-
console.log("To configure manually, add to .
|
|
1094
|
+
console.log("To configure manually, add to .cstl/config.yaml:");
|
|
1026
1095
|
console.log("");
|
|
1027
1096
|
console.log(chalk.cyan(" packages:"));
|
|
1028
1097
|
console.log(chalk.cyan(" frontend:"));
|
|
@@ -1439,8 +1508,8 @@ export async function init(options) {
|
|
|
1439
1508
|
console.log(chalk.yellow(` ${result.message}`));
|
|
1440
1509
|
console.log(chalk.gray(" Falling back to blank templates..."));
|
|
1441
1510
|
const retryCmd = registry
|
|
1442
|
-
? `
|
|
1443
|
-
: `
|
|
1511
|
+
? `cstl init --registry ${registry.gigetSource} --template ${selectedTemplate}`
|
|
1512
|
+
: `cstl init --template ${selectedTemplate}`;
|
|
1444
1513
|
console.log(chalk.gray(` You can retry later: ${retryCmd}`));
|
|
1445
1514
|
}
|
|
1446
1515
|
}
|
|
@@ -1481,7 +1550,7 @@ export async function init(options) {
|
|
|
1481
1550
|
else {
|
|
1482
1551
|
console.log(chalk.yellow(` ${result.message}`));
|
|
1483
1552
|
console.log(chalk.gray(" Falling back to blank templates..."));
|
|
1484
|
-
console.log(chalk.gray(` You can retry later:
|
|
1553
|
+
console.log(chalk.gray(` You can retry later: cstl init --registry ${registry.gigetSource}`));
|
|
1485
1554
|
}
|
|
1486
1555
|
}
|
|
1487
1556
|
// ==========================================================================
|
|
@@ -1522,7 +1591,7 @@ export async function init(options) {
|
|
|
1522
1591
|
{
|
|
1523
1592
|
type: "confirm",
|
|
1524
1593
|
name: "byok",
|
|
1525
|
-
message: "使用 Cursor++ BYOK 代理?(原生 Cursor API 用户选 No;仅 BYOK 需要 .
|
|
1594
|
+
message: "使用 Cursor++ BYOK 代理?(原生 Cursor API 用户选 No;仅 BYOK 需要 .cstl/local/cursor2plus/)",
|
|
1526
1595
|
default: false,
|
|
1527
1596
|
},
|
|
1528
1597
|
]);
|
|
@@ -1546,14 +1615,28 @@ export async function init(options) {
|
|
|
1546
1615
|
// Write version file for update tracking
|
|
1547
1616
|
const versionPath = path.join(cwd, DIR_NAMES.WORKFLOW, ".version");
|
|
1548
1617
|
fs.writeFileSync(versionPath, VERSION);
|
|
1549
|
-
// Configure selected tools by copying entire directories (dogfooding)
|
|
1618
|
+
// Configure selected tools by copying entire directories (dogfooding).
|
|
1619
|
+
// In coexistence mode cursor-trellis takes over `.cursor/` — force-write
|
|
1620
|
+
// platform files even when `-y`/`--skipExisting` is set, so cstl hooks,
|
|
1621
|
+
// rules, and commands land regardless of upstream files already present.
|
|
1550
1622
|
const selectedPlatformIds = [];
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1623
|
+
const savedMode = getWriteMode();
|
|
1624
|
+
if (coexistenceMode) {
|
|
1625
|
+
setWriteMode("force");
|
|
1626
|
+
}
|
|
1627
|
+
try {
|
|
1628
|
+
for (const tool of tools) {
|
|
1629
|
+
const platformId = resolveCliFlag(tool);
|
|
1630
|
+
if (platformId) {
|
|
1631
|
+
selectedPlatformIds.push(platformId);
|
|
1632
|
+
console.log(chalk.blue(`📝 Configuring ${AI_TOOLS[platformId].name}...`));
|
|
1633
|
+
await configurePlatform(platformId, cwd);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
finally {
|
|
1638
|
+
if (coexistenceMode) {
|
|
1639
|
+
setWriteMode(savedMode);
|
|
1557
1640
|
}
|
|
1558
1641
|
}
|
|
1559
1642
|
if (selectedPlatformIds.includes("cursor")) {
|
|
@@ -1569,7 +1652,7 @@ export async function init(options) {
|
|
|
1569
1652
|
logCursor2plusSetupHint();
|
|
1570
1653
|
}
|
|
1571
1654
|
// Create root files (skip if exists)
|
|
1572
|
-
await createRootFiles(cwd);
|
|
1655
|
+
await createRootFiles(cwd, coexistenceMode);
|
|
1573
1656
|
}
|
|
1574
1657
|
finally {
|
|
1575
1658
|
stopRecordingWrites();
|
|
@@ -1580,7 +1663,7 @@ export async function init(options) {
|
|
|
1580
1663
|
console.log(chalk.gray(`📋 Tracking ${hashedCount} template files for updates`));
|
|
1581
1664
|
}
|
|
1582
1665
|
// Non-native workflow is user-managed local content. Drop the
|
|
1583
|
-
// `.
|
|
1666
|
+
// `.cstl/workflow.md` hash entry so `trellis update` classifies it as
|
|
1584
1667
|
// modified and does not silently restore native bytes. See design.md
|
|
1585
1668
|
// "Durable-state contract".
|
|
1586
1669
|
if (workflowMdOverride !== undefined && workflowId !== NATIVE_WORKFLOW_ID) {
|
|
@@ -1605,7 +1688,7 @@ export async function init(options) {
|
|
|
1605
1688
|
// isFirstInit=false + no .developer file → joiner onboarding (fresh clone)
|
|
1606
1689
|
// isFirstInit=false + .developer exists → same-dev re-init, no task
|
|
1607
1690
|
//
|
|
1608
|
-
// Tasks-empty fallback (issue #204): if .
|
|
1691
|
+
// Tasks-empty fallback (issue #204): if .cstl/ exists but tasks dir is
|
|
1609
1692
|
// empty, the previous init aborted before creating the bootstrap task. Run
|
|
1610
1693
|
// bootstrap creation regardless of isFirstInit. writeTaskSkeleton is
|
|
1611
1694
|
// idempotent so repeated triggers are safe.
|
|
@@ -1616,7 +1699,10 @@ export async function init(options) {
|
|
|
1616
1699
|
const tasksDir = path.join(cwd, PATHS.TASKS);
|
|
1617
1700
|
const tasksEmpty = !fs.existsSync(tasksDir) || fs.readdirSync(tasksDir).length === 0;
|
|
1618
1701
|
if (isFirstInit || tasksEmpty) {
|
|
1619
|
-
createBootstrapTask(cwd, developerName, pythonCmd, projectType, monorepoPackages);
|
|
1702
|
+
const bootstrapCreated = createBootstrapTask(cwd, developerName, pythonCmd, projectType, selectedCapabilities, monorepoPackages);
|
|
1703
|
+
if (bootstrapCreated) {
|
|
1704
|
+
console.log(chalk.gray(`Next: complete ${BOOTSTRAP_TASK_NAME} to verify selected capabilities and fill the project spec.`));
|
|
1705
|
+
}
|
|
1620
1706
|
}
|
|
1621
1707
|
else if (!hadDeveloperFileAtStart) {
|
|
1622
1708
|
try {
|
|
@@ -1645,8 +1731,28 @@ function askInput(prompt) {
|
|
|
1645
1731
|
});
|
|
1646
1732
|
});
|
|
1647
1733
|
}
|
|
1648
|
-
async function createRootFiles(cwd) {
|
|
1734
|
+
async function createRootFiles(cwd, coexistenceMode = false) {
|
|
1649
1735
|
const agentsPath = path.join(cwd, FILE_NAMES.AGENTS);
|
|
1736
|
+
if (coexistenceMode && fs.existsSync(agentsPath)) {
|
|
1737
|
+
// Coexistence: preserve an upstream `<!-- TRELLIS:START -->` block and any
|
|
1738
|
+
// user content, and add/refresh the `<!-- CSTL:START -->` block alongside.
|
|
1739
|
+
// Force-write the merged result (via writeFile so the write is recorded
|
|
1740
|
+
// for hash tracking) even under `-y`.
|
|
1741
|
+
const existing = fs.readFileSync(agentsPath, "utf-8");
|
|
1742
|
+
const merged = insertCstlManagedBlock(existing, agentsMdContent);
|
|
1743
|
+
const saved = getWriteMode();
|
|
1744
|
+
setWriteMode("force");
|
|
1745
|
+
try {
|
|
1746
|
+
const wrote = await writeFile(agentsPath, merged);
|
|
1747
|
+
if (wrote) {
|
|
1748
|
+
console.log(chalk.blue("📄 Updated AGENTS.md with cursor-trellis managed block (preserved upstream block)"));
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
finally {
|
|
1752
|
+
setWriteMode(saved);
|
|
1753
|
+
}
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1650
1756
|
// Write AGENTS.md from template
|
|
1651
1757
|
const agentsWritten = await writeFile(agentsPath, agentsMdContent);
|
|
1652
1758
|
if (agentsWritten) {
|