Installer Skills

Flow Skill: Detect repository root and validate target path FLSK_UBFLOW_INST_001
status: draft
tags: ubflow, installer
  1. Run: git rev-parse --show-toplevel

  2. On exit code 128: abort with "Not inside a Git repository. Aborting."

  3. Prompt target_docs_path with default docs/.

  4. Resolve: target_abs_path = os.path.abspath(os.path.join(repo_root, answer))

  5. Verify target_abs_path.startswith(repo_root) and os.path.isdir(target_abs_path). On failure, re-prompt with an inline error.

Flow Skill: Resolve SemVer tags from remote template FLSK_UBFLOW_INST_002
status: draft
tags: ubflow, installer
  1. Run: git ls-remote --tags <template_url>

  2. Extract tags matching r'refs/tags/(v\d+\.\d+\.\d+)$'

  3. Sort descending using packaging.version.Version

  4. Present as a select prompt template_version

  5. Pass the selection to Copier via --vcs-ref <template_version>

Flow Skill: Invoke Copier in interactive, replay, pretend, and update modes FLSK_UBFLOW_INST_003
status: draft
tags: ubflow, installer
employed_by: AGENT_INSTALLER
linked_tool: FLTL_COPIER

Interactive (first install):

copier copy --trust --vcs-ref <version> <template_url> <target_abs_path>

Replay / CI (deterministic):

copier copy --answers-file .copier-answers.yml --trust \
  --vcs-ref <version> <template_url> <target_abs_path>

Pretend diff (before upgrade):

copier update --pretend --vcs-ref <new_version> --trust <target_abs_path>

Execute upgrade:

copier update --vcs-ref <new_version> --trust <target_abs_path>
Flow Skill: Write and verify the installation manifest FLSK_UBFLOW_INST_004
status: draft
tags: ubflow, installer

Writing (post-generation hook tasks/finalize.py):

  1. Walk all files written to target_abs_path in this run.

  2. Compute hashlib.sha256(file_bytes).hexdigest() for each file.

  3. Write <target_abs_path>/.ubflow-manifest.json:

    {
      "schema_version": 1,
      "template_url": "...",
      "template_version": "v1.2.0",
      "installed_at": "<ISO-8601 UTC>",
      "files": { "rel/path": "sha256:<hex>" }
    }
    

Verifying (ubflow-installer verify <path>):

  1. Read manifest, recompute digests, compare.

  2. Print FAIL  <path>  (expected <a>, got <b>) for each mismatch.

  3. Exit 0 if all match; exit 2 otherwise.

Flow Skill: Check prerequisites and optionally auto-install FLSK_UBFLOW_INST_005
status: draft
tags: ubflow, installer

Copier pre-generation hook tasks/check_prerequisites.py:

  1. Check sys.version_info >= (3, 11)

  2. Check importlib.metadata.version("sphinx-needs") >= "2.0.0"

  3. Check shutil.which("copier") and version >= 9.0.0

  4. Check shutil.which("java") — warning only, non-blocking

  5. Print all failures. Exit 1 if any hard check failed.

  6. If only Python packages are missing, prompt "Install missing packages now? [y/N]". On y: run python -m pip install "sphinx-needs>=2.0.0" "copier>=9.0.0" On n: print the manual install command and exit 1.

Flow Skill: Scan for Sphinx-Needs ID and file-path conflicts FLSK_UBFLOW_INST_006
status: draft
tags: ubflow, installer

Copier pre-generation hook tasks/check_conflicts.py:

ID collision scan:

  1. Collect template IDs from template RST sources: re.findall(r'^\s+:id:\s+(\S+)', text, re.MULTILINE)

  2. Scan all *.rst under the repo root with the same pattern.

  3. On collision print: CONFLICT  <ID>  found in: <path>:<line>

  4. Exit 1 if any collision exists.

File-path collision prompt:

  1. Collect all output paths that already exist on disk.

  2. For each existing path prompt: EXISTS  <rel_path>  overwrite? [y/N]

  3. Files answered N are excluded from render output.

  4. If all colliding files are skipped, exit 1 and report incomplete installation.

Flow Skill: Write files atomically via staging and roll back on failure FLSK_UBFLOW_INST_007
status: draft
tags: ubflow, installer

Copier post-generation hook tasks/finalize.py:

  1. Create a temporary staging directory (tempfile.mkdtemp()).

  2. Write all rendered files to staging first.

  3. Move each file from staging to target_abs_path (os.replace).

  4. On any exception: a. Delete staging directory. b. Remove moved target files using the in-progress manifest. c. Print "Installation failed. All written files have been removed." d. Exit 1.

  5. On success, write the manifest (see FLSK_UBFLOW_INST_004).

Flow Skill: Scan installed RST for undefined Sphinx-Needs references FLSK_UBFLOW_INST_008
status: draft
tags: ubflow, installer

Copier post-generation hook tasks/validate.py:

  1. Parse all installed RST files with:

    re.findall(
        r':(?:satisfies|implements|supports|applies|employs|uses|covered_by):\s+(.+)',
        text
    )
    
  2. Split each match on ; or whitespace to get individual IDs.

  3. For each ID call ubCode MCP find_needs(need_id=<id>). Fall back to local RST scan if MCP is unavailable.

  4. Print UNDEF  <ID>  referenced in: <path>:<line> for each missing ID.

  5. Exit 1 if undefined references exist.

  6. On pass, invoke:

    sphinx-build -b html -W --keep-going <docs_root> <docs_root>/_build/html
    
Flow Skill: Write the ubFlow agent stub file FLSK_UBFLOW_INST_009
status: draft
tags: ubflow, installer
employed_by: AGENT_INSTALLER
linked_tool: FLTL_GIT

To deploy .github/agents/ubflow.agent.md idempotently:

  1. Ensure the directory .github/agents/ exists in the target repository root; create it if necessary.

  2. The file content to write is exactly:

    ---
    description: ubFlow — needs-driven agent design for GitHub Copilot
    applyTo: '**'
    ---
    
    Fetch your full instruction and skill set from the ubCode MCP server
    before doing anything else:
    
    1. Call `get_schema_for_need_filter` with `agent="ubflow"` to verify
       the ubCode extension is reachable.
    2. Call `query_needs` with `type="flowinst"`, `tags=["ubflow"]`, and
       `agent="ubflow"` to load all binding instructions.
    3. Call `query_needs` with `type="flowskill"`, `tags=["ubflow"]`, and
       `agent="ubflow"` to load all skills.
    
    If any call returns `{"error": "unknown_agent"}` or fails, stop and
    ask the user to install or update the ubCode VS Code extension.
    
  3. Check whether .github/agents/ubflow.agent.md already exists:

    • Does not exist → write the file; report Created .github/agents/ubflow.agent.md.

    • Exists, content identical → skip silently.

    • Exists, content differs → overwrite; report Updated .github/agents/ubflow.agent.md (content changed).

  4. Do not stage or commit the file — leave that to the standard post-install git workflow.

Flow Skill: Write the companion bootstrap instructions file FLSK_UBFLOW_INST_010
status: draft
tags: ubflow, installer
employed_by: AGENT_INSTALLER

To deploy .github/instructions/<family_name>.instructions.md idempotently:

  1. Read family_name and orchestrator_id from the family’s ubflow_package.json (fields package_name and orchestrator_agent_id). If orchestrator_agent_id is absent, derive it as AGT_<FAMILY_NAME_UPPER>_ORCHESTRATOR.

  2. Read ubproject_path from ubflow_package.json (field ubproject_path). Default: ubflow/<family_name>/ubproject.toml.

  3. Ensure the directory .github/instructions/ exists in the target repository root; create it if necessary.

  4. Compose the file content:

    ---
    applyTo: '**'
    ---
    ## ubFlow Bootstrap — <family_name> family
    
    When operating as `@<family_name>`:
    
    1. Call `mcp_ubcode_get_schema_for_need_filter` with
       `file_path: <ubproject_path>`.
    2. Call `mcp_ubcode_get_data_for_single_need` with
       `id: <orchestrator_id>`.
    3. Load every need linked via `:applies:` and `:employs:`.
    4. Only then respond to the user request.
    
    Do **not** skip these steps. If any MCP call fails, halt and ask
    the user to check the ubCode extension.
    
  5. Check whether the file already exists:

    • Does not exist → write the file; report CREATED  .github/instructions/<family_name>.instructions.md.

    • Exists, content identical → skip silently.

    • Exists, content differs → overwrite; report UPDATED  .github/instructions/<family_name>.instructions.md (content changed).

  6. Do not stage or commit the file — leave that to the standard post-install git workflow.