Skip to content
Merged
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
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export default defineConfig({
link: "/guides/user/building-custom-agents",
},
{ text: "Running Agents Locally", link: "/guides/user/running-agents-locally" },
{ text: "Issue Commands", link: "/guides/user/issues-commands" },
{ text: "Jira Integration", link: "/guides/user/jira-integration" },
{ text: "How To Emit Traces", link: "/guides/user/how-to-emit-traces" },
{ text: "Tracing with MLflow", link: "/guides/user/tracing-with-mlflow" },
Expand Down
14 changes: 13 additions & 1 deletion docs/guides/dev/cli-internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,18 @@ fullsend
│ ├── output # Scan agent output for leaked secrets
│ ├── context # Scan context files for prompt injection
│ └── url # Validate URLs against SSRF attacks
├── issues # Read and write issue content across trackers
│ ├── get # Read issue content (title, body, comments, labels)
│ │ ├── --tracker <tracker> # Tracker backend: github, gitlab, or jira
│ │ ├── --project <project> # Project: owner/repo (GitHub/GitLab) or key (Jira)
│ │ └── --number <int> # Issue number
│ └── post-comment # Post or update a sticky comment on an issue
│ ├── --tracker <tracker> # Tracker backend: github, gitlab, or jira
│ ├── --project <project> # Project: owner/repo (GitHub/GitLab) or key (Jira)
│ ├── --number <int> # Issue number
│ └── --marker <string> # Hidden HTML marker for idempotent updates
├── post-review # Post PR review comments to GitHub
├── post-comment # Post issue/PR comments to GitHub
├── post-comment # Post issue/PR comments to GitHub (deprecated)
└── reconcile-status # Finalize orphaned status comments
├── --repo <owner/repo> # Repository in owner/repo format
├── --number <int> # Issue/PR number
Expand Down Expand Up @@ -650,6 +660,8 @@ var executableFiles = map[string]struct{}{
| `internal/cli/mint.go` | ~1022 | Mint deploy/enroll/unenroll/status |
| `internal/cli/inference.go` | ~408 | Inference WIF provision/status |
| `internal/cli/github.go` | ~966 | GitHub setup/set/status/uninstall/sync-scaffold/enroll/unenroll |
| `internal/cli/issues.go` | ~430 | Issue read/write commands (`fullsend issues get`, `post-comment`) |
| `internal/cli/tracker_client.go` | ~122 | Tracker client factory (GitHub/GitLab/Jira) |
| `internal/cli/run.go` | ~1923 | Agent execution lifecycle |
| `internal/mint/main.go` | ~95 | GCF token mint entry point (wiring only) |
| `cmd/mint/` | ~285 | Standalone mint server (no GCP dependency) |
Expand Down
13 changes: 13 additions & 0 deletions docs/guides/infrastructure/layered-config-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ the overlay → base → code defaults chain.
| `agents` | `[]AgentEntry` | Keyed merge by `DerivedName()` | `nil` (none) |
| `allowed_remote_resources` | `[]string` | Union with deny-all | `DefaultAllowedRemoteResources()` |
| `forge` | `string` | Scalar override | `""` (GitHub) |
| `tracker` | `string` | Scalar override | `""` (none) |
| `mint_url` | `string` | Scalar override | `DefaultPerRepoMintURL` (hosted public mint) |
| `inference.provider` | `string` (nested) | Scalar override | `"vertex"` |
| `inference.project` | `string` (nested) | Scalar override | `""` (empty) |
Expand Down Expand Up @@ -151,6 +152,17 @@ inference:
# inference.wif_provider: ...base... (from base)
```

### `tracker` — scalar override

**`tracker`** stores the default issue tracker for `fullsend issues`
commands (`github`, `gitlab`, or `jira`). Unset (`""`) means no default
— `--tracker` is required on every `fullsend issues` invocation. When
set, it is used as the default for `--tracker` on both `fullsend issues
get` and `fullsend issues post-comment`; an explicit `--tracker` flag
overrides it. Distinct from `forge`: a repo's hosting forge does not
imply its issue tracker (e.g. a GitHub-hosted repo may track issues in
Jira).

### `roles` — replace if set

The `roles` field uses replace-if-set semantics with **no union**:
Expand Down Expand Up @@ -296,6 +308,7 @@ compiled-in defaults apply:
| `agents` | `nil` (none configured) |
| `allowed_remote_resources` | `["https://raw.githubusercontent.com/fullsend-ai/fullsend/", "https://raw.githubusercontent.com/fullsend-ai/agents/"]` |
| `forge` | `""` (GitHub) |
| `tracker` | `""` (none — `--tracker` is required unless set) |
| `mint_url` | `"https://fullsend-mint-gljhbkcloq-uc.a.run.app"` (hosted public mint) |
| `inference.provider` | `"vertex"` |
| `inference.project` | `""` (empty — must be provided) |
Expand Down
130 changes: 130 additions & 0 deletions docs/guides/user/issues-commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Issue Commands

Read and write issue content across GitHub, GitLab, and Jira from
custom agent scripts using `fullsend issues get` and
`fullsend issues post-comment`.

## When to use

The built-in agent pipeline handles comment posting automatically for
GitHub-sourced events. Use these commands when:

- A custom agent needs to post results back to **Jira** or **GitLab**.
- An agent script needs to **read** issue content (title, body, labels,
comments) from any tracker as structured JSON.
- You need **sticky comments** (find-and-update-by-marker) on a
non-GitHub tracker.

## `fullsend issues get`

Reads an issue's title, body, labels, and comments from the specified
tracker and prints them as JSON.

```bash
fullsend issues get \
--tracker github \
--project owner/repo \
--number 42
```

For Jira, `--project` is the project key and `--number` is the numeric
issue ID (not the human-readable key):

```bash
fullsend issues get \
--tracker jira \
--project PROJ \
--number 101 \
--jira-url https://myteam.atlassian.net \
--jira-email you@example.com
```

### Flags

| Flag | Required | Description |
|------|----------|-------------|
| `--tracker` | Yes (unless config default set) | Tracker backend: `github`, `gitlab`, or `jira` |
| `--project` | Yes | Project identifier: `owner/repo` (GitHub/GitLab) or project key (Jira) |
| `--number` | Yes | Issue number (must be a positive integer) |
| `--token` | No | API token (default: env var per tracker) |
| `--jira-url` | Jira only | Jira instance URL (default: `$JIRA_BASE_URL`) |
| `--jira-email` | Jira only | Jira user email for auth (default: `$JIRA_USER_EMAIL`) |
| `--fullsend-dir` | No | Path to `.fullsend` config directory (sources a default `--tracker` from its `config.yaml`) |

## `fullsend issues post-comment`

Posts a comment with a hidden HTML marker on an issue. On re-runs,
finds the existing comment by its marker and edits in-place, collapsing
old content into `<details>` blocks. This prevents comment flooding
on re-runs.

```bash
echo "Triage complete. See PR #99." | fullsend issues post-comment \
--tracker jira \
--project PROJ \
--number 101 \
--marker "<!-- fullsend:triage-agent -->" \
--jira-url https://myteam.atlassian.net \
--jira-email you@example.com
```

### Flags

| Flag | Required | Description |
|------|----------|-------------|
| `--tracker` | Yes (unless config default set) | Tracker backend: `github`, `gitlab`, or `jira` |
| `--project` | Yes | Project identifier: `owner/repo` (GitHub/GitLab) or project key (Jira) |
| `--number` | Yes | Issue number (must be a positive integer) |
| `--marker` | Yes | Hidden HTML marker for idempotent updates (e.g. `<!-- fullsend:my-agent -->`) |
| `--result` | No | Path to comment body file, or `-` for stdin (default: `-`) |
| `--token` | No | API token (default: env var per tracker) |
| `--jira-url` | Jira only | Jira instance URL (default: `$JIRA_BASE_URL`) |
| `--jira-email` | Jira only | Jira user email for auth (default: `$JIRA_USER_EMAIL`) |
| `--dry-run` | No | Print what would be posted without making API calls |
| `--fullsend-dir` | No | Path to `.fullsend` config directory (sources a default `--tracker` from its `config.yaml`) |

### Jira marker constraints

For `--tracker jira`, the `--marker` value must not contain `\`, `*`,
`_`, `` ` ``, `[`, `]`, or `&`. Jira's markdown round-trip escapes
these characters, which would break marker re-detection on later runs.

## Config-based default tracker

Set a default tracker in `.fullsend/config.yaml` to avoid passing
`--tracker` on every invocation:

```yaml
tracker: jira
```

Then pass `--fullsend-dir .fullsend` (or let the agent pipeline supply
it). An explicit `--tracker` flag overrides the config default. See
[Layered Config Reference](../infrastructure/layered-config-reference.md)
for how the `tracker` field resolves through the config overlay chain.

## Trust model

Marker-based comment lookup does not verify the comment author. In a
trusted CI environment (the intended deployment) this is safe because
only the bot writes marker-bearing comments. If untrusted users can
post issue comments containing your marker string, they could cause
the bot to edit their comment instead of creating its own. Do not use
this command in environments where untrusted users can write arbitrary
issue comments bearing your marker.

## Environment variables

| Variable | Tracker | Description |
|----------|---------|-------------|
| `GH_TOKEN` or `GITHUB_TOKEN` | GitHub | GitHub API token |
| `GITLAB_TOKEN` | GitLab | GitLab API token |
| `JIRA_TOKEN` | Jira | Jira API token |
| `JIRA_BASE_URL` | Jira | Jira instance URL |
| `JIRA_USER_EMAIL` | Jira | Email for Jira Cloud Basic auth |

## See also

- [Jira Integration](jira-integration.md) -- polling and dispatch setup
- [Bring Your Own Agent](bring-your-own-agent.md) -- adding custom agents
- [Layered Config Reference](../infrastructure/layered-config-reference.md) -- config field documentation
11 changes: 4 additions & 7 deletions docs/guides/user/jira-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,11 @@ A slash command is only recognized as the **first token of the comment's first l

The `event_type` field in dispatch records (e.g. `"comment_added"`, `"label_changed"`) describes the Jira-side activity that **triggered** the dispatch — it is an **input** event, not a description of what the agent will do. When you see `event_type: "comment_added"` in `dispatches.json`, it means "a comment was added to a Jira issue, and that comment matched a routing rule." It says nothing about the agent's output.

Currently, agents process Jira-sourced dispatches but write all results — comments, labels, status updates — back to **GitHub only**. No output is posted to Jira. The agent runs against the target GitHub repo exactly as it would for a GitHub-sourced event: triage output becomes a GitHub issue comment, code agent output becomes a pull request, and so on. The Jira issue that triggered the dispatch receives no automatic update.
Currently, agents process Jira-sourced dispatches but write all results — comments, labels, status updates — back to **GitHub only** by default. The agent runs against the target GitHub repo exactly as it would for a GitHub-sourced event: triage output becomes a GitHub issue comment, code agent output becomes a pull request, and so on. The Jira issue that triggered the dispatch receives no automatic update.

This means the person who commented `/fs-triage` on a Jira issue will not see the triage result in Jira — they need to check the linked GitHub repo. Two follow-ups track closing this gap:
The CLI primitive for posting comments to Jira exists — `fullsend issues post-comment --tracker jira` — along with the underlying `tracker.Client` Jira implementation ([#5989](https://github.com/fullsend-ai/fullsend/issues/5989)). However, the built-in agent pipeline does not use it yet: agent pre/post scripts still expect a GitHub issue number, not a Jira key ([#2264](https://github.com/fullsend-ai/fullsend/issues/2264)).

- [#2264](https://github.com/fullsend-ai/fullsend/issues/2264) — agent pre/post scripts do not understand Jira work-item payloads (they expect a GitHub issue number, not a Jira key)
- [#5989](https://github.com/fullsend-ai/fullsend/issues/5989) — Jira comment write support and a `tracker.Client` for Jira, which would allow agents to post results back to the originating Jira issue

Until both land, treat Jira as a **trigger source only**: it can start agent work, but all output appears in GitHub.
This means the person who commented `/fs-triage` on a Jira issue will not see the triage result in Jira — they need to check the linked GitHub repo. Until agent-pipeline integration lands ([#2264](https://github.com/fullsend-ai/fullsend/issues/2264)), treat Jira as a **trigger source only** for built-in agents: it can start agent work, but all output appears in GitHub. Custom agents can use `fullsend issues post-comment --tracker jira` directly to post results back to Jira.

## Prerequisites

Expand All @@ -60,7 +57,7 @@ Until both land, treat Jira as a **trigger source only**: it can start agent wor

## Repo configuration

No special harness or config changes are needed to *receive* Jira-sourced dispatches: the Jira poller produces the same [NormalizedEvents](../../normative/normalized-event/v1/) that GitHub and GitLab do, so routing and triggers work unchanged. However, agent output is currently written to GitHub only — no results are posted back to Jira. See [Event semantics — input only](#event-semantics--input-only) for details and tracking issues. Additionally, the built-in agents' pre/post scripts do not yet understand Jira work-item payloads (they expect a GitHub issue number, not a Jira key — [#2264](https://github.com/fullsend-ai/fullsend/issues/2264)), so dispatched agent runs will not complete successfully until that follow-up lands. See the Troubleshooting section below.
No special harness or config changes are needed to *receive* Jira-sourced dispatches: the Jira poller produces the same [NormalizedEvents](../../normative/normalized-event/v1/) that GitHub and GitLab do, so routing and triggers work unchanged. However, built-in agent output is currently written to GitHub only — the CLI primitive for posting to Jira exists (`fullsend issues post-comment --tracker jira`), but the agent pipeline does not use it yet. See [Event semantics — input only](#event-semantics--input-only) for details. Additionally, the built-in agents' pre/post scripts do not yet understand Jira work-item payloads (they expect a GitHub issue number, not a Jira key — [#2264](https://github.com/fullsend-ai/fullsend/issues/2264)), so dispatched agent runs will not complete successfully until that follow-up lands. See the Troubleshooting section below.

If your repo already has a `.fullsend/config.yaml` from `fullsend github setup`, you are ready to go.

Expand Down
Loading
Loading