Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

All notable changes to the Specify CLI and templates are documented here.

# [0.12.15+adlc10] - 2026-07-19

### Added

- **Neutral team-ai-directives scaffolding**: Added
`specify team-directives init [PATH] [--name NAME]` to create a consumable
team knowledge base without cloning Tikal-specific directives. The command
generates neutral manifest, constitution, CDR, skill registry, MCP example,
agent navigation, and tracked empty context directories. It does not create
team policy, initialize Git, or attach the knowledge base to a project.
- **Safe scaffold writes**: New destinations and existing empty directories are
supported. Files, symlinks, and non-empty directories are rejected, and
partial filesystem writes are rolled back.
- **Capability reporting**: `specify version --features` now advertises
`team_directives_init` for automation and agent feature detection.

# [0.12.15+adlc9] - 2026-07-17

### Fixed
Expand Down
1 change: 1 addition & 0 deletions FORK.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ When a fork release changes only bundled extension behavior, keep the CLI versio

| Version | Date | Base Upstream | Changes |
|---------|------|---------------|---------|
| 0.12.15+adlc10 | 2026-07-19 | 0.12.15 (`ad601e5d`) | Added `specify team-directives init [PATH] [--name NAME]` for creating a neutral, consumable team-ai-directives knowledge base without cloning Tikal defaults. The scaffold includes manifest/version metadata, an explicitly empty constitution and CDR index, compatible empty skill registries, an MCP example, AGENTS.md navigation, and tracked context/skill directories. It accepts absent or empty destinations, rejects occupied or symlink targets, rolls back partial writes, does not initialize Git, and advertises the capability through `specify version --features`. |
| 0.12.15+adlc9 | 2026-07-17 | 0.12.15 (`ad601e5d`) | Bug fixes in team-boot and team-discover model-invocation commands: (1) team-boot Step 2 used glob to find constitution — `{TEAM_AI_DIRECTIVES}` was treated as a search target, not a resolved value; added explicit definition after Step 1 and direct-read instruction in Step 2. (2) team-discover Step 2 had no plain-message fallback — expected `{REPO_ROOT}/specs/${SPECIFY_FEATURE}/context.md` which doesn't exist when invoked as a skill from team-boot; added fallback to extract feature context from user's message. (3) team-discover mode detection missing skill-invocation case — all 4 rules depended on `$ARGUMENTS`/env vars/hook context; added rule 5: skill invocation defaults to no-write mode with inline output. (4) team-discover Step 4 didn't surface external skills — `.skills.json` `external` map entries never matched against feature context; expanded matching to cover both `default` and `external` lists with category-based matching. (5) team-discover Step 1 `{TEAM_AI_DIRECTIVES}` undefined — same bare-variable pattern as team-boot; added clarifying note. team-ai-directives extension 4.3.2 → 4.3.3. |
| 0.12.15+adlc8 | 2026-07-17 | 0.12.15 (`ad601e5d`) | Canonical runtime event unification + 4 new hook-capable integrations. Extensions now use unified canonical event names (`PreToolUse`, `PostToolUse`, `Stop`, `SessionStart`, `SessionEnd`, `UserPromptSubmit`) in `runtime_hooks:`; each adapter translates to agent-native names via `CANONICAL_TO_NATIVE` mapping. New adapters: `QwenHookAdapter` (`.qwen/settings.json`), `GeminiHookAdapter` (`.gemini/settings.json`, `BeforeTool`/`AfterTool`), `DevinHookAdapter` (`.devin/hooks.v1.json`), `TabnineHookAdapter` (`.tabnine/agent/settings.json`). `validate_runtime_hooks()` rejects unknown event names. Adapters warn+skip unsupported events. `JSONHookAdapter` refactored with shared `_build_nested_fragment()` + `bridge_path_prefix`. Hook callout added to `TomlIntegration.setup()` + `YamlIntegration.setup()`. `--hooks` option added to gemini/qwen/devin/tabnine. 56 tests (22 new). |
| 0.12.15+adlc7 | 2026-07-16 | 0.12.15 (`ad601e5d`) | Bug fix: team-* model-invocation commands (`team.boot`, `team.discover`, `team.skills`) silently no-op on dotfile paths. Step 1 "Locate Knowledge Base" used ambiguous "Read `.specify/init-options.json`" instruction — agents interpreted as "search first" and used glob/find tools, which silently skip dotfile-prefixed path segments (`.specify/`). team-boot's Step 1 exit handler fired, skipping constitution load and team-discover invocation entirely, leaving the full team-ai-directives knowledge base invisible for the session. Replaced with explicit agent-agnostic instruction: "Read the file directly. Do NOT use glob, find, or any file-search tool." Adds walk-up fallback via successive direct reads (`../.specify/`, `../../.specify/`) for CWD resilience. team-ai-directives extension 4.3.1 → 4.3.2. |
Expand Down
17 changes: 15 additions & 2 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,19 @@ Our workflow supports multiple AI agents. Choose your preferred tool:

## 2. Project Initialization

### Create Team AI Directives

If your team does not already have a directives repository, create a neutral
one before initializing the project:

```bash
specify team-directives init ../team-ai-directives --name my-team
```

This creates the required knowledge-base structure without defining team
policies or initializing Git. Add and review your team's principles and context,
then place the repository under version control when ready.

### For New Projects

Initialize a new project with team AI directives:
Expand All @@ -72,8 +85,8 @@ Initialize a new project with team AI directives:
mkdir my-project
cd my-project

# Initialize with team-ai-directives
specify init . --team-ai-directives <DIRECTIVES_URL>
# Initialize with a local team-ai-directives knowledge base
specify init . --team-ai-directives ../team-ai-directives
```

### For Existing Projects
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,23 @@ This fork includes pre-installed presets (auto-installed during `specify init`):

## 🔧 Team AI Directives Integration

This fork supports team-ai-directives — a foundation for version-controlled AI agent behavior. Install during project initialization:
This fork supports team-ai-directives — a foundation for version-controlled AI agent behavior.

Create a neutral knowledge base for a new team:

```bash
# Creates ./team-ai-directives by default
specify team-directives init

# Or choose a path and manifest name
specify team-directives init ../platform-directives --name platform-team
```

The scaffold contains the required repository structure but no team policies,
personas, examples, skills, or MCP servers. It does not initialize Git. Review
and version the generated files according to your team's repository policy.

Install a knowledge base during project initialization:

```bash
# Install from GitHub archive (ZIP download)
Expand Down
29 changes: 29 additions & 0 deletions docs/reference/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,35 @@ specify init my-project --integration copilot --preset compliance

> **Symlinked project roots.** `SPECIFY_INIT_DIR` relocates *where* the project is, not *how* a command treats symlinks: each command keeps its existing cwd-path stance. Commands that traverse and write project files through broad input paths (`bundle`, `workflow run <file>`) refuse a symlinked `.specify/` to preserve write confinement. Other project-scoped commands keep their existing behavior when `SPECIFY_INIT_DIR` points at a project root, which may include following a symlinked `.specify/`.

## Initialize Team AI Directives

```bash
specify team-directives init [<path>] [--name <team-name>]
```

Creates a neutral team-ai-directives knowledge base at `<path>`, which defaults
to `./team-ai-directives`. When `--name` is omitted, the destination directory
name is stored in `manifest.yml`.

The generated repository includes an explicitly empty constitution and CDR
index, empty context and skill registries, an MCP configuration example, and
navigation for agents. It contains no team policy and does not initialize Git
or modify a Spec Kit project.

The destination may be absent or an existing empty directory. The command
rejects files, symlinks, and non-empty directories instead of overwriting them.

```bash
# Use the default path
specify team-directives init

# Choose a location and team name
specify team-directives init ../platform-directives --name platform-team

# Consume the local knowledge base during project initialization
specify init my-project --team-ai-directives ../platform-directives
```

## Check Installed Tools

```bash
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "agentic-sdlc-specify-cli"
version = "0.12.15+adlc9"
version = "0.12.15+adlc10"
description = "Specify CLI (tikalk fork). Agentic SDLC toolkit for Spec-Driven Development with pre-installed extensions and AI integrations."
readme = "README.md"
requires-python = ">=3.11"
Expand Down
7 changes: 7 additions & 0 deletions src/specify_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@ def _feature_capabilities() -> dict[str, bool]:
"multi_install_safe_registry_metadata": True,
"integration_upgrade_command": True,
"self_check_command": True,
"team_directives_init": True,
"workflow_catalog": True,
"bundled_templates": True,
}
Expand Down Expand Up @@ -692,6 +693,12 @@ def _require_specify_project() -> Path:
_register_bundle_cmds(app)


# ===== Team Directives Commands =====

from .commands.team_directives import register as _register_team_directives_cmds # noqa: E402
_register_team_directives_cmds(app)


# ===== Workflow Commands =====

# Moved to workflows/_commands.py — registered here to preserve CLI surface.
Expand Down
63 changes: 63 additions & 0 deletions src/specify_cli/commands/team_directives/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""``specify team-directives`` command group."""

from __future__ import annotations

from pathlib import Path

import typer

from ..._console import console, err_console

try:
from ..._init_fork import accent, make_typer
except ImportError:

def accent(text: str, **_kwargs) -> str:
return text

def make_typer(*, name=None, help=None, **kwargs):
kwargs.setdefault("add_completion", False)
return typer.Typer(name=name, help=help, **kwargs)


team_directives_app = make_typer(
name="team-directives",
help="Create and manage team-ai-directives knowledge bases",
)


@team_directives_app.command("init")
def team_directives_init(
path: Path = typer.Argument(
Path("team-ai-directives"),
help="Destination directory",
),
name: str | None = typer.Option(
None,
"--name",
help="Team name stored in manifest.yml (defaults to the directory name)",
),
):
"""Create a neutral team-ai-directives knowledge base."""
from ...team_directives_scaffold import scaffold_team_directives

try:
result = scaffold_team_directives(path, name)
except (OSError, ValueError) as exc:
err_console.print(f"[red]Error:[/red] {exc}")
raise typer.Exit(1)

console.print(
f"{accent('Created team-ai-directives scaffold:', bold=True)} {result.root}"
)
console.print(
f"[dim]{len(result.files)} files created; no Git repository initialized.[/dim]"
)
console.print()
console.print("[bold]Next step:[/bold]")
console.print(f'specify init <project> --team-ai-directives "{result.root}"')


def register(app: typer.Typer) -> None:
"""Register the team-directives command group on the root app."""
app.add_typer(team_directives_app, name="team-directives")
Loading