@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/update.js
CHANGED
|
@@ -5,6 +5,8 @@ import inquirer from "inquirer";
|
|
|
5
5
|
import { DIR_NAMES, FILE_NAMES, PATHS } from "../constants/paths.js";
|
|
6
6
|
import { VERSION, PACKAGE_NAME } from "../constants/version.js";
|
|
7
7
|
import { getMigrationsForVersion, getAllMigrations, getMigrationMetadata, getConfigSectionsAddedBetween, } from "../migrations/index.js";
|
|
8
|
+
import { assessCstlDirectoryMigrate } from "../utils/workflow-ownership.js";
|
|
9
|
+
import { isWorkflowInitialized, resolveWorkflowDirName, workflowPath, } from "../utils/workflow-dir.js";
|
|
8
10
|
import { loadHashes, saveHashes, updateHashes, isTemplateModified, removeHash, renameHash, computeHash, } from "../utils/template-hash.js";
|
|
9
11
|
import { compareVersions } from "../utils/compare-versions.js";
|
|
10
12
|
import { toPosix } from "../utils/posix.js";
|
|
@@ -25,13 +27,18 @@ import { runPostUpdateSmoke } from "../utils/post-update-smoke.js";
|
|
|
25
27
|
import { assertCursorRulesValid } from "../utils/validate-rules.js";
|
|
26
28
|
import { buildFilePlanFromChanges, createBaseRolloutReport, emitRolloutReport, migrationResultToSummary, summarizeMigrationPlan, } from "../utils/update-rollout-report.js";
|
|
27
29
|
import { snapshotReadinessForRollout } from "../utils/readiness.js";
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
+
function logCursor2plusCompatHint(cwd) {
|
|
31
|
+
const bundleDir = path.join(cwd, DIR_NAMES.WORKFLOW, "local", "cursor2plus");
|
|
32
|
+
if (!fs.existsSync(bundleDir)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
console.log(chalk.gray("\nCursor++ BYOK: after Cursor/Cursor++ upgrades, run `python .cstl/local/cursor2plus/patch_wpelc8.py --check-compat` before re-applying Method 2.5."));
|
|
36
|
+
}
|
|
37
|
+
const CSTL_BLOCK_START = "<!-- CSTL:START -->";
|
|
38
|
+
const CSTL_BLOCK_END = "<!-- CSTL:END -->";
|
|
39
|
+
const LEGACY_TRELLIS_BLOCK_START = "<!-- TRELLIS:START -->";
|
|
40
|
+
const LEGACY_TRELLIS_BLOCK_END = "<!-- TRELLIS:END -->";
|
|
30
41
|
const LEGACY_UNTRACKED_AGENTS_MD_BLOCK_HASHES = new Set([
|
|
31
|
-
// v0.5.0-beta.17 and earlier wrote AGENTS.md but did not hash-track it.
|
|
32
|
-
// This hash is the pristine Trellis-managed block before the Subagents
|
|
33
|
-
// section was added, so old untouched projects can be updated without a
|
|
34
|
-
// false "modified by you" conflict.
|
|
35
42
|
"c1f511b1cfc1902f2147da159f09cc51f380b0c9e341cdb3ac5dea5233f3e307",
|
|
36
43
|
]);
|
|
37
44
|
// Paths that should never be touched (true user data)
|
|
@@ -43,23 +50,37 @@ const PROTECTED_PATHS = [
|
|
|
43
50
|
`${DIR_NAMES.WORKFLOW}/.developer`,
|
|
44
51
|
`${DIR_NAMES.WORKFLOW}/.current-task`,
|
|
45
52
|
];
|
|
53
|
+
function getAgentsBlockMarkers(content) {
|
|
54
|
+
if (content.includes(CSTL_BLOCK_START)) {
|
|
55
|
+
return { start: CSTL_BLOCK_START, end: CSTL_BLOCK_END };
|
|
56
|
+
}
|
|
57
|
+
if (content.includes(LEGACY_TRELLIS_BLOCK_START)) {
|
|
58
|
+
return {
|
|
59
|
+
start: LEGACY_TRELLIS_BLOCK_START,
|
|
60
|
+
end: LEGACY_TRELLIS_BLOCK_END,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
46
65
|
function getTrellisManagedBlock(content) {
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
66
|
+
const markers = getAgentsBlockMarkers(content);
|
|
67
|
+
if (!markers) {
|
|
49
68
|
return null;
|
|
50
69
|
}
|
|
51
|
-
const
|
|
70
|
+
const start = content.indexOf(markers.start);
|
|
71
|
+
const end = content.indexOf(markers.end, start);
|
|
52
72
|
if (end === -1) {
|
|
53
73
|
return null;
|
|
54
74
|
}
|
|
55
|
-
return content.slice(start, end +
|
|
75
|
+
return content.slice(start, end + markers.end.length);
|
|
56
76
|
}
|
|
57
77
|
function replaceTrellisManagedBlock(existingContent, templateContent) {
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
78
|
+
const existingMarkers = getAgentsBlockMarkers(existingContent);
|
|
79
|
+
if (!existingMarkers) {
|
|
60
80
|
return null;
|
|
61
81
|
}
|
|
62
|
-
const
|
|
82
|
+
const existingStart = existingContent.indexOf(existingMarkers.start);
|
|
83
|
+
const existingEnd = existingContent.indexOf(existingMarkers.end, existingStart);
|
|
63
84
|
if (existingEnd === -1) {
|
|
64
85
|
return null;
|
|
65
86
|
}
|
|
@@ -69,7 +90,28 @@ function replaceTrellisManagedBlock(existingContent, templateContent) {
|
|
|
69
90
|
}
|
|
70
91
|
return (existingContent.slice(0, existingStart) +
|
|
71
92
|
templateBlock +
|
|
72
|
-
existingContent.slice(existingEnd +
|
|
93
|
+
existingContent.slice(existingEnd + existingMarkers.end.length));
|
|
94
|
+
}
|
|
95
|
+
function includesCstlRuntimeDirRename(migrations) {
|
|
96
|
+
return migrations.some((item) => item.type === "rename-dir" &&
|
|
97
|
+
item.from === ".trellis" &&
|
|
98
|
+
item.to === ".cstl");
|
|
99
|
+
}
|
|
100
|
+
function upgradeAgentsMdToCstlMarkers(cwd) {
|
|
101
|
+
const agentsPath = path.join(cwd, FILE_NAMES.AGENTS);
|
|
102
|
+
if (!fs.existsSync(agentsPath)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const content = fs.readFileSync(agentsPath, "utf-8");
|
|
106
|
+
if (!content.includes(LEGACY_TRELLIS_BLOCK_START)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const upgraded = content
|
|
110
|
+
.replace(LEGACY_TRELLIS_BLOCK_START, CSTL_BLOCK_START)
|
|
111
|
+
.replace(LEGACY_TRELLIS_BLOCK_END, CSTL_BLOCK_END)
|
|
112
|
+
.replace(/\.\/\.trellis\//g, "./.cstl/")
|
|
113
|
+
.replace(/(?<![A-Za-z0-9_])\.trellis\//g, ".cstl/");
|
|
114
|
+
fs.writeFileSync(agentsPath, upgraded, "utf-8");
|
|
73
115
|
}
|
|
74
116
|
function buildAgentsMdTemplate(cwd) {
|
|
75
117
|
const fullPath = path.join(cwd, FILE_NAMES.AGENTS);
|
|
@@ -201,27 +243,64 @@ function printSafeFileDeleteSummary(classified) {
|
|
|
201
243
|
console.log("");
|
|
202
244
|
}
|
|
203
245
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
246
|
+
* Commands-only policy residue notice. Cursor's configurator stopped shipping
|
|
247
|
+
* `.cursor/skills/` (commit acd41a92, v0.2.8); projects initialized before
|
|
248
|
+
* that carry stale skill directories that pollute the `/` palette with
|
|
249
|
+
* internal auto-triggered skills and create command+skill double entries for
|
|
250
|
+
* `finish-work`.
|
|
251
|
+
*
|
|
252
|
+
* Safe-file-delete migrations (added in v0.2.10) remove pristine copies
|
|
253
|
+
* automatically; this notice surfaces residue that survives (user-modified
|
|
254
|
+
* files, or dry-run preview) so the user knows what remains and why.
|
|
207
255
|
*/
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
256
|
+
const CURSOR_SKILL_RESIDUE_DIRS = [
|
|
257
|
+
// Current cstl-* names (post-0.3.0)
|
|
258
|
+
"cstl-brainstorm",
|
|
259
|
+
"cstl-before-dev",
|
|
260
|
+
"cstl-check",
|
|
261
|
+
"cstl-break-loop",
|
|
262
|
+
"cstl-update-spec",
|
|
263
|
+
"cstl-finish-work",
|
|
264
|
+
"cstl-micro-grill",
|
|
265
|
+
"cstl-meta",
|
|
266
|
+
"cstl-skill-creator",
|
|
267
|
+
"cstl-spec-bootstrap",
|
|
268
|
+
"cstl-cursor2plus-setup",
|
|
269
|
+
"smart-search-cli",
|
|
270
|
+
// Legacy trellis-* names also checked for residue detection (pre-0.3.0 projects)
|
|
271
|
+
"trellis-brainstorm",
|
|
272
|
+
"trellis-before-dev",
|
|
273
|
+
"trellis-check",
|
|
274
|
+
"trellis-break-loop",
|
|
275
|
+
"trellis-update-spec",
|
|
276
|
+
"trellis-finish-work",
|
|
277
|
+
"trellis-micro-grill",
|
|
278
|
+
"trellis-meta",
|
|
279
|
+
"trellis-skill-creator",
|
|
280
|
+
"trellis-spec-bootstrap",
|
|
281
|
+
"trellis-cursor2plus-setup",
|
|
282
|
+
];
|
|
283
|
+
function printCursorSkillResidueNotice(cwd) {
|
|
284
|
+
const skillsRoot = path.join(cwd, ".cursor", "skills");
|
|
285
|
+
if (!fs.existsSync(skillsRoot))
|
|
286
|
+
return;
|
|
287
|
+
const foundResidues = [];
|
|
288
|
+
for (const dir of CURSOR_SKILL_RESIDUE_DIRS) {
|
|
289
|
+
if (fs.existsSync(path.join(skillsRoot, dir))) {
|
|
290
|
+
foundResidues.push(dir);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (foundResidues.length === 0)
|
|
220
294
|
return;
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"
|
|
224
|
-
console.log(chalk.
|
|
295
|
+
const hasFinishWorkCmd = fs.existsSync(path.join(cwd, ".cursor", "commands", "cstl-finish-work.md"));
|
|
296
|
+
const hasFinishWorkSkill = foundResidues.includes("cstl-finish-work") ||
|
|
297
|
+
foundResidues.includes("trellis-finish-work");
|
|
298
|
+
console.log(chalk.cyan(" Cursor commands-only skill residue notice:"));
|
|
299
|
+
console.log(chalk.yellow(` Found ${foundResidues.length} stale skill director${foundResidues.length === 1 ? "y" : "ies"} under .cursor/skills/ from before the commands-only policy.`));
|
|
300
|
+
console.log(chalk.gray(` Pristine copies are auto-removed by safe-file-delete; user-modified files are kept (review manually).`));
|
|
301
|
+
if (hasFinishWorkCmd && hasFinishWorkSkill) {
|
|
302
|
+
console.log(chalk.gray(" trellis-finish-work appears as BOTH command and skill — safe-file-delete resolves the duplicate when the skill copy is pristine."));
|
|
303
|
+
}
|
|
225
304
|
console.log("");
|
|
226
305
|
}
|
|
227
306
|
/**
|
|
@@ -245,7 +324,7 @@ function executeSafeFileDeletes(classified, cwd) {
|
|
|
245
324
|
return deleted;
|
|
246
325
|
}
|
|
247
326
|
/**
|
|
248
|
-
* Load update.skip paths from .
|
|
327
|
+
* Load update.skip paths from .cstl/config.yaml
|
|
249
328
|
*
|
|
250
329
|
* Parses simple YAML structure:
|
|
251
330
|
* update:
|
|
@@ -256,8 +335,8 @@ function executeSafeFileDeletes(classified, cwd) {
|
|
|
256
335
|
* @internal Exported for testing only
|
|
257
336
|
*/
|
|
258
337
|
export function loadUpdateSkipPaths(cwd) {
|
|
259
|
-
const configPath =
|
|
260
|
-
if (!fs.existsSync(configPath))
|
|
338
|
+
const configPath = workflowPath(cwd, "config.yaml");
|
|
339
|
+
if (!configPath || !fs.existsSync(configPath))
|
|
261
340
|
return [];
|
|
262
341
|
try {
|
|
263
342
|
const content = fs.readFileSync(configPath, "utf-8");
|
|
@@ -671,7 +750,9 @@ async function promptConflictResolution(file, options, applyToAll) {
|
|
|
671
750
|
*/
|
|
672
751
|
function createBackupDirPath(cwd) {
|
|
673
752
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
674
|
-
|
|
753
|
+
const workflowRoot = workflowPath(cwd, `.backup-${timestamp}`) ??
|
|
754
|
+
path.join(cwd, DIR_NAMES.WORKFLOW, `.backup-${timestamp}`);
|
|
755
|
+
return workflowRoot;
|
|
675
756
|
}
|
|
676
757
|
/**
|
|
677
758
|
* Backup a single file to the backup directory
|
|
@@ -773,15 +854,16 @@ function createFullBackup(cwd) {
|
|
|
773
854
|
* Update version file
|
|
774
855
|
*/
|
|
775
856
|
function updateVersionFile(cwd) {
|
|
776
|
-
const
|
|
857
|
+
const dirName = resolveWorkflowDirName(cwd) ?? DIR_NAMES.WORKFLOW;
|
|
858
|
+
const versionPath = path.join(cwd, dirName, ".version");
|
|
777
859
|
fs.writeFileSync(versionPath, VERSION);
|
|
778
860
|
}
|
|
779
861
|
/**
|
|
780
862
|
* Get current installed version
|
|
781
863
|
*/
|
|
782
864
|
function getInstalledVersion(cwd) {
|
|
783
|
-
const versionPath =
|
|
784
|
-
if (fs.existsSync(versionPath)) {
|
|
865
|
+
const versionPath = workflowPath(cwd, ".version");
|
|
866
|
+
if (versionPath && fs.existsSync(versionPath)) {
|
|
785
867
|
return fs.readFileSync(versionPath, "utf-8").trim();
|
|
786
868
|
}
|
|
787
869
|
return "unknown";
|
|
@@ -913,7 +995,7 @@ function classifyMigrations(migrations, cwd, hashes, templates) {
|
|
|
913
995
|
continue;
|
|
914
996
|
}
|
|
915
997
|
// For non-rename types, also block writing TO protected paths
|
|
916
|
-
// rename/rename-dir are allowed to target protected paths (e.g., 0.2.0 renames into .
|
|
998
|
+
// rename/rename-dir are allowed to target protected paths (e.g., 0.2.0 renames into .cstl/workspace)
|
|
917
999
|
if (item.to &&
|
|
918
1000
|
isProtectedPath(item.to) &&
|
|
919
1001
|
item.type !== "rename" &&
|
|
@@ -1266,7 +1348,7 @@ async function executeMigrations(classified, cwd, options) {
|
|
|
1266
1348
|
}
|
|
1267
1349
|
// For `backup-rename`, leave an inline .backup copy of the user's modified
|
|
1268
1350
|
// original next to the new location (for rename) or in place (for delete).
|
|
1269
|
-
// This is in addition to the full project snapshot at .
|
|
1351
|
+
// This is in addition to the full project snapshot at .cstl/.backup-*/;
|
|
1270
1352
|
// the inline copy is more discoverable when the user wants to diff or merge
|
|
1271
1353
|
// their customizations against the new template.
|
|
1272
1354
|
if (item.type === "rename" && item.to) {
|
|
@@ -1291,7 +1373,7 @@ async function executeMigrations(classified, cwd, options) {
|
|
|
1291
1373
|
const filePath = path.join(cwd, item.from);
|
|
1292
1374
|
if (action === "backup-rename") {
|
|
1293
1375
|
// Keep a .backup copy in place before deletion so the user can recover
|
|
1294
|
-
// inline without digging through .
|
|
1376
|
+
// inline without digging through .cstl/.backup-*/.
|
|
1295
1377
|
fs.copyFileSync(filePath, filePath + ".backup");
|
|
1296
1378
|
}
|
|
1297
1379
|
fs.unlinkSync(filePath);
|
|
@@ -1352,7 +1434,7 @@ function releaseBlockersFromReadiness(readiness, cliBehindNpm, cliVersion, lates
|
|
|
1352
1434
|
blockers.push({
|
|
1353
1435
|
code: "cli_behind_npm",
|
|
1354
1436
|
message: `CLI ${cliVersion} is behind npm ${latestNpmVersion}`,
|
|
1355
|
-
recovery: ["
|
|
1437
|
+
recovery: ["cstl upgrade"],
|
|
1356
1438
|
});
|
|
1357
1439
|
}
|
|
1358
1440
|
if (!readiness.skipped && !readiness.smartSearch.ok) {
|
|
@@ -1361,7 +1443,7 @@ function releaseBlockersFromReadiness(readiness, cliBehindNpm, cliVersion, lates
|
|
|
1361
1443
|
message: "Smart Search readiness did not pass",
|
|
1362
1444
|
recovery: [
|
|
1363
1445
|
"smart-search doctor --format json",
|
|
1364
|
-
"
|
|
1446
|
+
"cstl update --skip-readiness",
|
|
1365
1447
|
],
|
|
1366
1448
|
});
|
|
1367
1449
|
}
|
|
@@ -1370,7 +1452,7 @@ function releaseBlockersFromReadiness(readiness, cliBehindNpm, cliVersion, lates
|
|
|
1370
1452
|
blockers.push({
|
|
1371
1453
|
code: `capability_${cap.id}`,
|
|
1372
1454
|
message: `Capability ${cap.id} readiness failed`,
|
|
1373
|
-
recovery: ["
|
|
1455
|
+
recovery: ["cstl update --skip-readiness"],
|
|
1374
1456
|
});
|
|
1375
1457
|
}
|
|
1376
1458
|
}
|
|
@@ -1428,10 +1510,10 @@ export async function update(options) {
|
|
|
1428
1510
|
});
|
|
1429
1511
|
finishRollout(options, report);
|
|
1430
1512
|
};
|
|
1431
|
-
// Check if
|
|
1432
|
-
if (!
|
|
1513
|
+
// Check if cursor-trellis is initialized (.cstl/ or legacy .trellis/)
|
|
1514
|
+
if (!isWorkflowInitialized(cwd)) {
|
|
1433
1515
|
console.log(chalk.red("Error: Trellis not initialized in this directory."));
|
|
1434
|
-
console.log(chalk.gray("Run '
|
|
1516
|
+
console.log(chalk.gray("Run 'cstl init' first."));
|
|
1435
1517
|
emitEarly("blocked_not_initialized");
|
|
1436
1518
|
return;
|
|
1437
1519
|
}
|
|
@@ -1441,13 +1523,13 @@ export async function update(options) {
|
|
|
1441
1523
|
setupProxy();
|
|
1442
1524
|
checkSmartSearchReadiness({
|
|
1443
1525
|
skipReadiness: options.skipReadiness,
|
|
1444
|
-
skipReadinessCommand: "
|
|
1526
|
+
skipReadinessCommand: "cstl update --skip-readiness",
|
|
1445
1527
|
});
|
|
1446
1528
|
checkProjectCapabilityReadiness({
|
|
1447
1529
|
cwd,
|
|
1448
1530
|
selected: loadProjectCapabilities(cwd),
|
|
1449
1531
|
skipReadiness: options.skipReadiness,
|
|
1450
|
-
skipReadinessCommand: "
|
|
1532
|
+
skipReadinessCommand: "cstl update --skip-readiness",
|
|
1451
1533
|
});
|
|
1452
1534
|
readinessSnapshot = snapshotReadinessForRollout({
|
|
1453
1535
|
cwd,
|
|
@@ -1476,7 +1558,7 @@ export async function update(options) {
|
|
|
1476
1558
|
// Check if CLI is outdated compared to npm
|
|
1477
1559
|
if (cliVsNpm < 0 && latestNpmVersion) {
|
|
1478
1560
|
console.log(chalk.yellow(`⚠️ Your CLI (${cliVersion}) is behind npm (${latestNpmVersion}).`));
|
|
1479
|
-
console.log(chalk.yellow(` Run:
|
|
1561
|
+
console.log(chalk.yellow(` Run: cstl upgrade\n`));
|
|
1480
1562
|
}
|
|
1481
1563
|
// Check for downgrade situation
|
|
1482
1564
|
if (cliVsProject < 0) {
|
|
@@ -1484,8 +1566,8 @@ export async function update(options) {
|
|
|
1484
1566
|
console.log(chalk.red(` This would DOWNGRADE your project!\n`));
|
|
1485
1567
|
if (!options.allowDowngrade) {
|
|
1486
1568
|
console.log(chalk.gray("Solutions:"));
|
|
1487
|
-
console.log(chalk.gray(` 1. Update your CLI:
|
|
1488
|
-
console.log(chalk.gray(` 2. Force downgrade:
|
|
1569
|
+
console.log(chalk.gray(` 1. Update your CLI: cstl upgrade`));
|
|
1570
|
+
console.log(chalk.gray(` 2. Force downgrade: cstl update --allow-downgrade\n`));
|
|
1489
1571
|
emitEarly("blocked_downgrade");
|
|
1490
1572
|
return;
|
|
1491
1573
|
}
|
|
@@ -1498,13 +1580,13 @@ export async function update(options) {
|
|
|
1498
1580
|
// Handle unknown version - skip regular migrations but safe-file-delete still runs
|
|
1499
1581
|
const isUnknownVersion = projectVersion === "unknown";
|
|
1500
1582
|
if (isUnknownVersion) {
|
|
1501
|
-
console.log(chalk.yellow("⚠️ No version file found. Skipping migrations — run
|
|
1583
|
+
console.log(chalk.yellow("⚠️ No version file found. Skipping migrations — run cstl init to fix."));
|
|
1502
1584
|
console.log(chalk.gray(" Template updates will still be applied."));
|
|
1503
1585
|
console.log(chalk.gray(" Safe file cleanup will still run (hash-verified).\n"));
|
|
1504
1586
|
}
|
|
1505
1587
|
// Self-heal poisoned manifests: prune entries that no current platform
|
|
1506
1588
|
// configurator owns. This silently removes user-owned paths that early
|
|
1507
|
-
// buggy versions of `
|
|
1589
|
+
// buggy versions of `cstl init` over-hashed (e.g. legacy session dirs).
|
|
1508
1590
|
{
|
|
1509
1591
|
const configuredPlatforms = new Set(getConfiguredPlatforms(cwd));
|
|
1510
1592
|
const prune = pruneOrphanManifestKeys(cwd, [...configuredPlatforms], hashes);
|
|
@@ -1530,7 +1612,7 @@ export async function update(options) {
|
|
|
1530
1612
|
})();
|
|
1531
1613
|
// Collect templates (used for both migration classification and change analysis)
|
|
1532
1614
|
const templates = collectTemplateFiles(cwd, breakingBypass);
|
|
1533
|
-
|
|
1615
|
+
printCursorSkillResidueNotice(cwd);
|
|
1534
1616
|
// Load update.skip paths (used for both safe-file-delete and template collection)
|
|
1535
1617
|
const skipPaths = loadUpdateSkipPaths(cwd);
|
|
1536
1618
|
// Collect safe-file-delete items from ALL manifests (hash match is the safety net)
|
|
@@ -1592,7 +1674,7 @@ export async function update(options) {
|
|
|
1592
1674
|
console.log(chalk.bgRed.white.bold(" ✖ MIGRATION REQUIRED ") +
|
|
1593
1675
|
chalk.red(` Breaking changes between ${projectVersion} → ${cliVersion} require --migrate.`));
|
|
1594
1676
|
console.log("");
|
|
1595
|
-
console.log(chalk.yellow(` Run:
|
|
1677
|
+
console.log(chalk.yellow(` Run: cstl update --migrate`));
|
|
1596
1678
|
console.log("");
|
|
1597
1679
|
console.log(chalk.gray(" Without --migrate, renamed/relocated files from breaking releases aren't moved,\n" +
|
|
1598
1680
|
" leaving your project with stale paths alongside new templates.\n" +
|
|
@@ -1770,7 +1852,7 @@ export async function update(options) {
|
|
|
1770
1852
|
// pipeline, or any redirected-stdin context). Guide the operator toward an
|
|
1771
1853
|
// explicit consent flag or a dry-run first.
|
|
1772
1854
|
if (!process.stdin.isTTY) {
|
|
1773
|
-
throw new Error("Non-interactive `
|
|
1855
|
+
throw new Error("Non-interactive `cstl update` requires an explicit consent flag. " +
|
|
1774
1856
|
"Re-run with --force (apply all), --skip-all (preserve modified), --create-new (.new copies), or --dry-run (preview only).");
|
|
1775
1857
|
}
|
|
1776
1858
|
const { proceed } = await inquirer.prompt([
|
|
@@ -1795,14 +1877,31 @@ export async function update(options) {
|
|
|
1795
1877
|
}
|
|
1796
1878
|
// Execute migrations if --migrate flag is set
|
|
1797
1879
|
if (options.migrate && classifiedMigrations) {
|
|
1880
|
+
const pendingRenameItems = [
|
|
1881
|
+
...classifiedMigrations.auto,
|
|
1882
|
+
...classifiedMigrations.confirm,
|
|
1883
|
+
...classifiedMigrations.conflict,
|
|
1884
|
+
];
|
|
1885
|
+
if (includesCstlRuntimeDirRename(pendingRenameItems)) {
|
|
1886
|
+
const assessment = assessCstlDirectoryMigrate(cwd, {
|
|
1887
|
+
forceCstlMigrate: options.forceCstlMigrate,
|
|
1888
|
+
});
|
|
1889
|
+
if (!assessment.ok) {
|
|
1890
|
+
console.error(chalk.red("Error:"), assessment.reason);
|
|
1891
|
+
process.exit(1);
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1798
1894
|
migrationApplyResult = await executeMigrations(classifiedMigrations, cwd, {
|
|
1799
1895
|
force: options.force,
|
|
1800
1896
|
skipAll: options.skipAll,
|
|
1801
1897
|
});
|
|
1802
1898
|
printMigrationResult(migrationApplyResult);
|
|
1899
|
+
if (includesCstlRuntimeDirRename(pendingRenameItems)) {
|
|
1900
|
+
upgradeAgentsMdToCstlMarkers(cwd);
|
|
1901
|
+
}
|
|
1803
1902
|
// Hardcoded: Rename traces-*.md to journal-*.md in workspace directories
|
|
1804
1903
|
// Why hardcoded: The migration system only supports fixed path renames, not pattern-based.
|
|
1805
|
-
// traces-*.md files are in .
|
|
1904
|
+
// traces-*.md files are in .cstl/workspace/{developer}/ with variable developer names
|
|
1806
1905
|
// and variable file numbers (traces-1.md, traces-2.md, etc.), so we can't enumerate them
|
|
1807
1906
|
// in the migration manifest. This is a one-time migration for the 0.2.0 naming redesign.
|
|
1808
1907
|
const workspaceDir = path.join(cwd, PATHS.WORKSPACE);
|
|
@@ -1969,6 +2068,7 @@ export async function update(options) {
|
|
|
1969
2068
|
}
|
|
1970
2069
|
const actionWord = isDowngrade ? "Downgrade" : "Update";
|
|
1971
2070
|
console.log(chalk.green(`\n✅ ${actionWord} complete! (${projectVersion} → ${cliVersion})`));
|
|
2071
|
+
logCursor2plusCompatHint(cwd);
|
|
1972
2072
|
if (createdNew > 0) {
|
|
1973
2073
|
console.log(chalk.gray("\nTip: Review .new files and merge changes manually if needed."));
|
|
1974
2074
|
}
|
|
@@ -2028,7 +2128,7 @@ export async function update(options) {
|
|
|
2028
2128
|
prdContent += `**From Version**: ${projectVersion}\n`;
|
|
2029
2129
|
prdContent += `**To Version**: ${cliVersion}\n`;
|
|
2030
2130
|
prdContent += `**Assignee**: ${currentDeveloper}\n\n`;
|
|
2031
|
-
prdContent += `## Status\n\n- [ ] Review migration guide\n- [ ] Update custom files\n- [ ] Run \`
|
|
2131
|
+
prdContent += `## Status\n\n- [ ] Review migration guide\n- [ ] Update custom files\n- [ ] Run \`cstl update --migrate\`\n- [ ] Test workflows\n\n`;
|
|
2032
2132
|
for (const { version, guide, aiInstructions, } of metadata.migrationGuides) {
|
|
2033
2133
|
prdContent += `---\n\n## v${version} Migration Guide\n\n`;
|
|
2034
2134
|
prdContent += guide;
|