Skip to content
Agent Orchestration
Skill

/init

Sets up Task Orchestrator for a project or for the user: creates (or finds) the project anchor root, writes the project: block into .taskorchestrator/config.yaml at the main checkout root, pushes it to the server, and seeds the bundled process rules. In project mode it also

BOOST
From plugin
task-orchestrator
20929 skills4 agents2 commands
Install
$ npx -y skills add jpicklyk/task-orchestrator --skill init --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/init

Context preview

The summary Claude sees to decide when to auto-load this skill.

Sets up Task Orchestrator for a project or for the user: creates (or finds) the project anchor root, writes the project: block into .taskorchestrator/config.yaml at the main checkout root, pushes it to the server, and seeds the bundled process rules. In project mode it also

SKILL.md

init.SKILL.md
name: init
description: "Sets up Task Orchestrator for a project or for the user: creates (or finds) the project anchor root, writes the project: block into .taskorchestrator/config.yaml at the main checkout root, pushes it to the server, and seeds the bundled process rules. In project mode it also writes a project-level client.json when the server is a loopback HTTP server. With --user it creates a personal root and writes the user-level config.yaml and client.json instead. Use when a user says: initialize task orchestrator, task-orchestrator init, set up task orchestrator for this project, set up a personal root, init --user, or when the SessionStart notice says to run /task-orchestrator:init. NOT Claude Code's built-in /init (that writes CLAUDE.md), NOT tutorial onboarding (quick-start), NOT migrating an already-populated unscoped database (adopt-project-scope), and NOT launching or reconfiguring the server (configure-server)."
argument-hint: "[--user] [project name]"

Init — Project and Personal Root Setup

The explicit setup step that the SessionStart notices point at (`/task-orchestrator:init` for a project, `/task-orchestrator:init --user` for a personal root). It creates or finds a root work item, records its id in a `project:` block of the right `config.yaml`, pushes that config to the server, and makes sure the bundled process rules are present for that root.

**Mode:** `--user` in `$ARGUMENTS` selects the personal-root flow. Any other non-flag text is the project (or root) name. No flag means project mode.

Everything is created through MCP tools; the skill never creates roots over REST.

---

Step 0 — Resolve paths

Resolve the plugin root: try `${CLAUDE_PLUGIN_ROOT}` (confirm the literal string `${CLAUDE_PLUGIN_ROOT}` did not survive into the command you are about to run); otherwise use the dev-checkout path `<git toplevel>/claude-plugins/task-orchestrator`. Call it `<plugin root>`.

Print the locator's view with one command (forward slashes only, no backslashes anywhere in it, because the Bash tool collapses them):

node --input-type=module -e "const m = await import('file:///<plugin root>/hooks/config-locator.mjs'); const l = m.locateConfig(); console.log(JSON.stringify({located: l, userHome: m.userHome(), userConfig: m.userConfigPath(), userClient: m.userClientPath(), TASK_ORCHESTRATOR_HOME: process.env.TASK_ORCHESTRATOR_HOME || null, AGENT_CONFIG_DIR: process.env.AGENT_CONFIG_DIR || null}, null, 2))"

Use the drive-letter form with forward slashes on Windows (`file:///D:/...`). If the plugin root cannot be resolved, derive the same paths by hand: the user home is `$TASK_ORCHESTRATOR_HOME` when non-empty, else the OS home; the user config is `<home>/.taskorchestrator/config.yaml`; the client file is `<home>/.taskorchestrator/client.json`.

Every later message names files by these resolved paths, never a hard-coded `~`.

Step 1 — Verify the server

Call `get_context()`. If the Task Orchestrator MCP tools are absent or the call errors, stop and point the user to `/task-orchestrator:configure-server`.

---

Project mode (default)

P1 — Find the main checkout root

The target root is the parent of `git rev-parse --path-format=absolute --git-common-dir` (this resolves to the main checkout even from a linked worktree). Not a git repository: use the current directory. Call it `<main>`.

  • **Refuse a home directory.** If `<main>` equals any home (`userHome()`, `os.homedir()`, or `os.userInfo().homedir`), stop: a config directly in a home directory is never a project config. Offer `/task-orchestrator:init --user` instead.
  • **Warn on `AGENT_CONFIG_DIR`.** When it is set, its config shadows the one about to be written; say which file wins.

P2 — Already initialized?

If `<main>/.taskorchestrator/config.yaml` exists with a non-empty `project.rootId`, the project is initialized. Skip to P5 (push), then the P5b `client.json` step, then Rule seeding, so an already-initialized project still gets its `client.json`. Re-running is idempotent.

P3 — Find or create the anchor

query_items(operation="search", type="project", depth=0)

Drop any item tagged `personal-root` from the results.

  • **Matches remain** -> `AskUserQuestion`: attach to one of them, create a new anchor, or abort. Attaching uses that item's id as `rootId`.
  • **No matches** -> census the depth-0 roots with `query_items(operation="overview")`. If roots exist other than the global containers (Session Retrospectives, Improvement Proposals, `agent-observation` items, `type=project` items), the database already holds unscoped work. Offer via `AskUserQuestion`: hand off to `/task-orchestrator:adopt-project-scope` (it creates the anchor, re-parents the work and writes the config; init then resumes at Rule seeding), create a fresh anchor and leave those roots alone, or abort.
  • **Nothing but global containers** -> create a fresh anchor.

Name: from `$ARGUMENTS`, else the main checkout's directory name; confirm with the user. Create it at depth 0:

manage_items(operation="create", items=[{title: "<name>", type: "project", priority: "low"}])

P4 — Write the `project:` block

Write at `<main>/.taskorchestrator/config.yaml`:

project:
  rootId: "<anchor-uuid>"
  name: "<name>"

Read-modify-write surgically: preserve all other content byte for byte; update an existing `project:` key in place rather than duplicating it. Create the file with only the block when it does not exist.

P5 — Push to the server

If a `manage_project_config` tool is available, push the full current file text:

manage_project_config(operation="push", rootId="<anchor-uuid>", configYaml="<full file text>")
  • Success: the returned `fingerprint` confirms it; re-pushing identical content returns the same fingerprint.
  • `VALIDATION_ERROR`: show the parse error; the local write is saved, so tell the user to fix the file and re-run (or `/manage-schemas validate`).
  • `CONFLICT_ERROR` (
Read more
Ships withtask-orchestrator

Server-enforced workflow discipline for AI agents. Prompt-based frameworks hope the LLM follows instructions. This one blocks the call if it doesn't.

Get the whole plugin

Other skills on task-orchestrator.