Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5aeb24e
docs(site): split the guide into per-topic pages
vmaerten Aug 30, 2026
c3b5b58
docs(site): turn the guide into an index with anchor redirects
vmaerten Aug 30, 2026
7e036aa
docs(site): add a docs landing page
vmaerten Aug 30, 2026
06dde89
docs(site): fill in missing page titles and descriptions
vmaerten Aug 30, 2026
2dfe782
docs(site): use relative links with extensions throughout
vmaerten Aug 30, 2026
337aea8
docs(site): restore the link definitions the split stranded
vmaerten Aug 30, 2026
4bb2aa4
docs(site): keep the released channel out of the docs landing page
vmaerten Aug 30, 2026
55aaa2b
docs(site): group the sidebar by reader intent
vmaerten Aug 30, 2026
498d7b1
docs(site): explain variable resolution order
vmaerten Aug 30, 2026
e2162ee
docs(site): explain dependencies and concurrency
vmaerten Aug 30, 2026
a7b8683
fix(site): stop the llms plugin from flattening output paths
vmaerten Aug 30, 2026
fdbd089
docs(site): add an entry point for coding agents
vmaerten Aug 30, 2026
82df461
feat(site): emit section and type metadata for search
vmaerten Aug 30, 2026
86a99c3
fix(site): clean the right dist directory
vmaerten Aug 30, 2026
77705d0
docs(site): define the missing link reference in the any-variables post
vmaerten Aug 30, 2026
f4f052e
docs(site): drop em dashes from the documentation
vmaerten Aug 30, 2026
f4b5148
docs(site): make the concurrency examples runnable
vmaerten Aug 30, 2026
e963498
docs(site): correct what secret and env actually do
vmaerten Aug 30, 2026
44e6f95
docs(site): fold the concepts pages into the guide
vmaerten Aug 30, 2026
d3642a7
feat(site): put the DocSearch crawler configuration in the repository
vmaerten Aug 30, 2026
a1454db
feat(site): harden the crawler configuration
vmaerten Aug 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions website/.vitepress/components/GuideRedirect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { onMounted, onUnmounted } from 'vue';
import { guideAnchors } from '../guideAnchors';

// The guide used to be a single page, so links to it in issues, blog posts and
// Stack Overflow answers point at anchors that now live on other pages. Netlify
// never receives the fragment, so this has to be resolved in the browser.
//
// location.replace rather than the VitePress router: the router leaves the new
// fragment unscrolled, and it pushes a history entry, so going back would land
// on the guide with the old hash still set and redirect again.
function resolve() {
const hash = window.location.hash.slice(1);
if (!hash) return;

const target = guideAnchors[decodeURIComponent(hash).toLowerCase()];
if (target) window.location.replace(target);
}

onMounted(() => {
resolve();
window.addEventListener('hashchange', resolve);
});

onUnmounted(() => window.removeEventListener('hashchange', resolve));
</script>

<template>
<span hidden />
</template>
26 changes: 25 additions & 1 deletion website/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,23 @@ export default defineConfig({
).href;
head.push(['link', { rel: 'canonical', href: canonicalUrl }]);

// The DocSearch crawler otherwise has to infer a record's section from the
// active sidebar link in the DOM. Stating it on the page is steadier: it
// survives a theme upgrade, and it is what hierarchy.lvl0 - the breadcrumb
// on every search result - should be set from.
if (pageData.frontmatter.section) {
head.push([
'meta',
{ name: 'docsearch:section', content: pageData.frontmatter.section }
])
}
if (pageData.frontmatter.docType) {
head.push([
'meta',
{ name: 'docsearch:doc_type', content: pageData.frontmatter.docType }
])
}

// Dynamic Open Graph and Twitter meta tags
const isHome = new URL(canonicalUrl).pathname === '/';
let pageTitle = pageData.frontmatter.title || pageData.title || taskName;
Expand Down Expand Up @@ -297,6 +314,11 @@ export default defineConfig({
srcDir: 'src',
cleanUrls: true,
srcExclude: [`${other}/**`, `${channel}/docs/**/template.md`],
// A function rather than the equivalent `{ '<channel>/:path*': ':path*' }`.
// vitepress-plugin-llms reuses this config to name its Markdown output, and
// on the object form it compiles the `:path*` array parameter back without
// separators, producing dist/docsreferencecli.md instead of
// dist/docs/reference/cli.md and breaking every relative link in them.
rewrites: (id) =>
id.startsWith(`${channel}/`) ? id.slice(channel.length + 1) : id,
markdown: {
Expand Down Expand Up @@ -381,7 +403,9 @@ export default defineConfig({
{ text: 'Home', link: '/' },
{
text: 'Docs',
link: '/docs/guide',
// The landing page only exists on next until cmd/release promotes it;
// the released channel still has to enter the section at the guide.
link: isLatest ? '/docs/guide' : '/docs/',
activeMatch: '^/docs'
},
{ text: 'Blog', link: '/blog', activeMatch: '^/blog' },
Expand Down
104 changes: 104 additions & 0 deletions website/.vitepress/guideAnchors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Where each section of the old single-page guide went when it was
// split up. Netlify never sees the URL fragment, so a _redirects rule
// cannot route these; GuideRedirect.vue resolves them in the browser.
export const guideAnchors: Record<string, string> = {
'running-taskfiles': '/docs/guide/running-tasks',
'supported-file-names': '/docs/guide/running-tasks#supported-file-names',
'running-a-taskfile-from-a-subdirectory':
'/docs/guide/running-tasks#running-a-taskfile-from-a-subdirectory',
'running-a-global-taskfile':
'/docs/guide/running-tasks#running-a-global-taskfile',
'running-a-taskfile-from-stdin':
'/docs/guide/running-tasks#running-a-taskfile-from-stdin',
'running-a-remote-taskfile':
'/docs/remote-taskfiles#specifying-a-remote-entrypoint',
'environment-variables': '/docs/guide/environment',
task: '/docs/guide/environment#task',
'env-files': '/docs/guide/environment#env-files',
'including-other-taskfiles': '/docs/guide/includes',
'remote-taskfiles': '/docs/guide/includes#remote-taskfiles',
'os-specific-taskfiles': '/docs/guide/includes#os-specific-taskfiles',
'directory-of-included-taskfile':
'/docs/guide/includes#directory-of-included-taskfile',
'optional-includes': '/docs/guide/includes#optional-includes',
'internal-includes': '/docs/guide/includes#internal-includes',
'flatten-includes': '/docs/guide/includes#flatten-includes',
'exclude-tasks-from-being-included':
'/docs/guide/includes#exclude-tasks-from-being-included',
'vars-of-included-taskfiles':
'/docs/guide/includes#vars-of-included-taskfiles',
'namespace-aliases': '/docs/guide/includes#namespace-aliases',
'internal-tasks': '/docs/guide/defining-tasks#internal-tasks',
'task-directory': '/docs/guide/defining-tasks#task-directory',
'task-dependencies': '/docs/guide/dependencies#task-dependencies',
'fail-fast-dependencies': '/docs/guide/dependencies#fail-fast-dependencies',
'platform-specific-tasks-and-commands':
'/docs/guide/platforms#platform-specific-tasks-and-commands',
'calling-another-task': '/docs/guide/dependencies#calling-another-task',
'prevent-unnecessary-work': '/docs/guide/up-to-date',
'by-fingerprinting-locally-generated-files-and-their-sources':
'/docs/guide/up-to-date#by-fingerprinting-locally-generated-files-and-their-sources',
'using-programmatic-checks-to-indicate-a-task-is-up-to-date':
'/docs/guide/up-to-date#using-programmatic-checks-to-indicate-a-task-is-up-to-date',
'using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies':
'/docs/guide/conditional-execution#using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies',
'conditional-execution-with-if':
'/docs/guide/conditional-execution#conditional-execution-with-if',
'task-level-if': '/docs/guide/conditional-execution#task-level-if',
'command-level-if': '/docs/guide/conditional-execution#command-level-if',
'using-templates-in-if-conditions':
'/docs/guide/conditional-execution#using-templates-in-if-conditions',
'using-if-with-for-loops':
'/docs/guide/conditional-execution#using-if-with-for-loops',
'if-vs-preconditions':
'/docs/guide/conditional-execution#if-vs-preconditions',
'limiting-when-tasks-run':
'/docs/guide/conditional-execution#limiting-when-tasks-run',
'ensuring-required-variables-are-set':
'/docs/guide/required-variables#ensuring-required-variables-are-set',
'ensuring-required-variables-have-allowed-values':
'/docs/guide/required-variables#ensuring-required-variables-have-allowed-values',
'using-variable-references-for-enum-values':
'/docs/guide/required-variables#using-variable-references-for-enum-values',
'prompting-for-missing-variables-interactively':
'/docs/guide/required-variables#prompting-for-missing-variables-interactively',
variables: '/docs/guide/variables',
'dynamic-variables': '/docs/guide/variables#dynamic-variables',
'referencing-other-variables':
'/docs/guide/variables#referencing-other-variables',
'parsing-json-yaml-into-map-variables':
'/docs/guide/variables#parsing-json-yaml-into-map-variables',
'secret-variables': '/docs/guide/variables#secret-variables',
'looping-over-values': '/docs/guide/loops',
'looping-over-a-static-list': '/docs/guide/loops#looping-over-a-static-list',
'looping-over-a-matrix': '/docs/guide/loops#looping-over-a-matrix',
'looping-over-your-task-s-sources-or-generated-files':
'/docs/guide/loops#looping-over-your-task-s-sources-or-generated-files',
'looping-over-variables': '/docs/guide/loops#looping-over-variables',
'renaming-variables': '/docs/guide/loops#renaming-variables',
'looping-over-tasks': '/docs/guide/loops#looping-over-tasks',
'looping-over-dependencies': '/docs/guide/loops#looping-over-dependencies',
'forwarding-cli-arguments-to-commands':
'/docs/guide/arguments#forwarding-cli-arguments-to-commands',
'wildcard-arguments': '/docs/guide/arguments#wildcard-arguments',
'doing-task-cleanup-with-defer':
'/docs/guide/dependencies#doing-task-cleanup-with-defer',
help: '/docs/guide/defining-tasks#help',
'display-summary-of-task':
'/docs/guide/defining-tasks#display-summary-of-task',
'task-aliases': '/docs/guide/defining-tasks#task-aliases',
'overriding-task-name': '/docs/guide/defining-tasks#overriding-task-name',
'warning-prompts': '/docs/guide/required-variables#warning-prompts',
'silent-mode': '/docs/guide/output#silent-mode',
'dry-run-mode': '/docs/guide/running-tasks#dry-run-mode',
'ignore-errors': '/docs/guide/output#ignore-errors',
'output-syntax': '/docs/guide/output#output-syntax',
'ci-integration': '/docs/guide/output#ci-integration',
'colored-output': '/docs/guide/output#colored-output',
'error-annotations': '/docs/guide/output#error-annotations',
'interactive-cli-application':
'/docs/guide/running-tasks#interactive-cli-application',
'short-task-syntax': '/docs/guide/defining-tasks#short-task-syntax',
'set-and-shopt': '/docs/guide/platforms#set-and-shopt',
'watch-tasks': '/docs/guide/watch'
};
Loading