# Task assistance — JUJU 0.7.0

Version 0.7.0 adds four coding-assistance capabilities through five tools. The
original 49 tools remain in the same order, followed by these five tools and the
20 tools in [MULTIMODAL.md](MULTIMODAL.md), for 74 tools total. These capabilities
are included in the 0.7.0 npm package. Upgrade instructions and feature limits are
in [RELEASE_0.7.0.md](RELEASE_0.7.0.md).

## Scope and existing authorization

| Tool | Existing scope | Execution / writes |
| --- | --- | --- |
| `context_for_task` | `juju:read` | Reads only; no model/API calls |
| `analyze_impact` | `juju:read` | Reads only |
| `read_symbol` | `juju:read` | Reads only |
| `preview_refactor` | `juju:write` | Stores an immutable plan; does not apply it |
| `verify_changes` | `juju:exec` in all modes | Plan/report do not launch commands; run uses existing exec approval |

All calls except `project_overview` still require the current `workspaceId` and
`workspaceEpoch`. OAuth, workspace ACLs, trust modes, secret/path guards, local
approval, command sandbox settings, desktop permissions and the existing change
journal are not reconfigured. No new security-management tool is added.

## 1. Context for a task

After `project_overview`, call `context_for_task` with the workspace identifiers
and, for example:

```json
{
  "goal": "แก้ OAuth refresh หลัง restart",
  "terms": ["refreshToken", "refresh_token", "ECONNRESET"],
  "files": ["src/auth/provider.ts"],
  "maxFiles": 6,
  "maxBytes": 16000
}
```

The example omits only the two workspace identifiers, which must be added to the
actual tool call. Results rank literal path/text/AST symbol matches and nearby
static dependencies. Each excerpt has its original path, raw-byte hash, 1-based
line range, category, reasons and a bounded declaration outline. Discovered task
recipes are returned as data; they are never executed by this read.

This is not vector/embedding search or natural-language reasoning inside JUJU.
Use explicit identifier/error terms, including English terms for a Thai goal.
The connected model remains responsible for interpreting the user's task.

## 2. Static impact analysis

```json
{
  "files": ["src/auth/provider.ts"],
  "maxResults": 40,
  "maxDepth": 5
}
```

`analyze_impact` follows reverse static import/re-export/import-equals edges using
the bundled TypeScript parser/resolver and the project's guarded compiler options.
It returns direct/transitive dependent files, dependency distance, the `via` file,
evidence line, hashes and related test paths. Configured path aliases and .js-to-.ts
resolution are supported when the relevant files are in the bounded snapshot.

It is file-level static impact, not a runtime call graph. Comments that look like
imports are not counted. Dynamic `import()`/`require()` calls and unresolved/external
imports are counted as limitations, not guessed into confirmed edges. Missing or
deleted targets have no historical graph in this version. `requiresBroadVerification`
remains true: the result is not permission to skip a full relevant gate, particularly
for shared configuration, authentication, or authorization code.

## 3. Read and preview an edit to a symbol

```json
{ "file": "src/example.ts", "symbol": "Example.run", "maxBytes": 12000 }
```

`read_symbol` returns the exact AST declaration rather than the whole file. It
supports TS/JS functions, classes, interfaces, named variables and methods, including
block-bodied arrow functions. Use a qualified name and optionally a line inside the
intended declaration when names/overloads are ambiguous. Ambiguity is an error, not
a guess. Expression-bodied arrows/classes/interfaces can be read but cannot be
body-edited through this version's refactor operation.

Use the returned file hash for `preview_refactor`:

```json
{
  "file": "src/example.ts",
  "symbol": "Example.run",
  "expectedHash": "sha256:<the exact hash returned by read_symbol>",
  "operation": "replace_body",
  "body": "\n    return 42;\n"
}
```

`body` is the interior only, without the surrounding braces. The preview rejects
stale hashes, ambiguous selectors, invalid syntax and attempts to escape the chosen
body. Unrelated file bytes are preserved and new line endings follow existing CRLF.
The complete resulting file is passed to the existing planner with its expected
hash; no alternative apply or rollback path is introduced.

Apply the returned `planId` and `planHash` with `apply_changes`, then use
`rollback_changes(changesetId, idempotencyKey)` when needed. Existing owner approval
and post-preview hash checks still apply. Syntax validation does not establish type
or behavior correctness; run verification afterwards.

## 4. Verification plan -> run -> report

`verify_changes` requires the existing exec scope in every mode because it is one
potentially executing tool. Clients restricted to read scope continue to use the
existing read-only `diagnostics` and `job_*` read tools.

### Plan (no execution)

```json
{ "mode": "plan", "files": ["src/example.ts"] }
```

Returns candidate task recipes, `status: not_run`, `notRun`, and
`freshness.baselineDigest`. Recipe names are discovery hints, not a guarantee that
project scripts are harmless. Review/select the desired scripts.

### Run (explicit selection)

```json
{
  "mode": "run",
  "files": ["src/example.ts"],
  "tasks": [{ "taskId": "npm:test:all", "recipeDigest": "sha256:<digest from plan>" }],
  "sourceDigest": "sha256:<plan.freshness.baselineDigest>",
  "idempotencyKey": "verify-example-001",
  "timeoutMs": 300000,
  "waitMs": 1000
}
```

Select only task IDs actually returned by the plan. Up to four tasks can run in
parallel if there are enough free slots under the existing concurrency limit. For
a sequential build/test pipeline, select the project's existing combined recipe.
The server validates the entire selection and source digest before launching. It
uses the existing job manager, owner approval mechanism, environment filtering and
configured sandbox defaults. It does not override sandbox/network policy, change
permissions, install dependencies, apply fixes, or automatically retry commands.

The returned `verificationId` is scoped to the workspace and principal. Reusing
the same idempotency key and arguments returns the same verification/jobs. An
uncertain persistence result is `RECOVERY_REQUIRED`, never an automatic repeat.

### Report (never launches work)

```json
{ "mode": "report", "verificationId": "verify_<id from run>" }
```

Reports status and existing job IDs. Existing `job_status`, `job_output`, `job_wait`
and `job_cancel` remain usable. A disconnected client does not cancel the owned jobs.

Statuses are `not_run`, `running`, `passed`, `failed`, `stale`, and `incomplete`.
A command with a nonzero exit code is a failure even if its output contains a
success message. Zero/unknown test counts or an all-skipped test run are not a
verified test pass. A successful non-test command is a command pass, not proof that
behavior tests ran. `notRun` lists other discovered recipes; it does not claim they
were covered by a nested script.

Vitest/Jest-style JSON on stdout is recognized when it fits the bounded log read;
individual failures are bounded. Vitest text fallback explicitly describes the last
recognized runner summary, not a total across nested scripts. Other reporters,
truncated/malformed reports and unknown output remain unverified. Raw logs are the
source for further investigation. Permission/port errors are environment hints only;
they do not turn a failing command into a pass or trigger a sandbox change.

### Freshness limits

The report fingerprints guarded, nonignored workspace files plus explicit targets
before execution and at report time, including relevant source/manifests/lockfiles
that fit the scan. Additions, deletions and modifications are reflected. Previously
observed drift is sticky even if a later check sees restored bytes. A runtime epoch
change prevents claiming fresh evidence.

This is **not** an immutable snapshot or continuous filesystem monitor. Changes
made and reverted between checks, ignored dependency/build trees, external services,
and environment differences cannot be proven unchanged. These limitations are also
returned in the tool data. If any fingerprint scan is incomplete, a successful
command is not promoted into a complete verification result.

## Bounds and implementation

Analysis runs in the existing time-bounded TypeScript worker and reads through
`WorkspaceFS`. No new dependency is installed. The scan is at most the smaller of
1000 files and the configured semantic cap, with a 16 MiB aggregate text budget and
512 KiB per parsed file (also bounded by the existing snapshot limit). Large files,
unresolved imports and truncated scans are reported. Explicit denied targets still
return the original path-policy error; they are not silently ignored.

Verification fingerprints at most 2000 files or the configured semantic cap,
2 MiB per file or the active read limit, and 32 MiB aggregate. It stores private
receipts in the existing state store, not in the repository. Returned data uses
explicit schemas and bounded summaries.

Implementation: `src/services/assistance/{contracts,analysis,verification}.ts`,
`src/tools/assistanceTools.ts`, and additive worker/catalog wiring. Regression tests:
`tests/unit/assistance.test.ts`, `tests/integration/assistance.test.ts`,
`tests/security/assistance.test.ts`.

## Activating version 0.7.0

Install `npm install -g juju-mcp@0.7.0`, then restart the intended JUJU HTTP/STDIO
process and refresh the client's 74-tool catalog. A source checkout can instead
run `npm run build`; building alone does not replace a global installation or the
code already loaded by a running process. Existing OAuth grants and workspace
permissions are retained; do not delete state as an upgrade step.

Browser automation and searchable demonstration workflows are included in the
separate [Multimodal module](MULTIMODAL.md). General project-memory search,
dependency-documentation integration, worktree isolation, general class refactors
and multi-language body edits are not included in this version.
