Skip to content

Commit 901f252

Browse files
committed
bump version 0.6.0 -> 0.7.0
0.7.0
1 parent 9b1214c commit 901f252

68 files changed

Lines changed: 5356 additions & 90 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/acpkit-sdk/SKILL.md

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,215 @@ Host-backed tools:
417417
- ACP Kit can expose client-backed filesystem and shell helpers
418418
- projection maps change how tools are rendered in ACP clients without changing the underlying tool contract
419419

420+
### HostAccessPolicy
421+
422+
`HostAccessPolicy` is ACP Kit's native typed guardrail surface for host-backed filesystem and terminal access.
423+
424+
Reach for it first when an integration has started inventing ad hoc rules such as:
425+
426+
- "warn for absolute paths but deny workspace escapes"
427+
- "show one caution in the client but enforce a different rule in the backend"
428+
- "treat command cwd and file paths as unrelated policy domains"
429+
430+
Use it:
431+
432+
- when host-backed file and terminal tools already exist
433+
- when approvals or projection warnings need to describe the same risk model that enforcement uses
434+
- when downstream code has started to accumulate one-off path checks
435+
436+
Do not reach for it:
437+
438+
- when the integration does not expose host-backed file or terminal tools at all
439+
- when the problem is product-specific approval wording rather than reusable access policy
440+
441+
Use it when an integration needs one reusable place to decide:
442+
443+
- whether absolute paths should only warn or hard fail
444+
- whether paths outside the active session cwd should warn or deny
445+
- whether workspace-root escapes should always deny
446+
- whether command cwd and command path arguments should follow the same policy language as file paths
447+
448+
Important distinction:
449+
450+
- `evaluate_path(...)` and `evaluate_command(...)` are for UI and approval surfaces
451+
- `enforce_path(...)` and `enforce_command(...)` are for actual blocking before ACP host requests are sent
452+
453+
The evaluation objects are intentionally UI-friendly. They expose:
454+
455+
- `disposition`
456+
- `headline`
457+
- `message`
458+
- `recommendation`
459+
- `risks`
460+
- `risk_codes`
461+
- `primary_risk`
462+
- `summary_lines()`
463+
464+
That means downstream integrations do not need to invent their own warning strings just to show a clear caution card.
465+
466+
Typical use:
467+
468+
```python
469+
from pydantic_acp import ClientHostContext, HostAccessPolicy
470+
471+
policy = HostAccessPolicy.strict()
472+
473+
host = ClientHostContext.from_session(
474+
client=client,
475+
session=session,
476+
access_policy=policy,
477+
workspace_root=session.cwd,
478+
)
479+
```
480+
481+
Small verified evaluation example:
482+
483+
```python
484+
from pathlib import Path
485+
486+
from pydantic_acp import HostAccessPolicy
487+
488+
policy = HostAccessPolicy.strict()
489+
evaluation = policy.evaluate_path(
490+
'../notes.txt',
491+
session_cwd=Path('/workspace/app'),
492+
workspace_root=Path('/workspace/app'),
493+
)
494+
495+
assert evaluation.disposition == 'deny'
496+
assert evaluation.should_deny
497+
assert 'outside_cwd' in evaluation.risk_codes
498+
```
499+
500+
Current presets:
501+
502+
- `HostAccessPolicy()` is conservative default behavior
503+
- `HostAccessPolicy.strict()` denies more aggressively outside the active cwd
504+
- `HostAccessPolicy.permissive()` keeps more paths executable but still surfaces risk
505+
506+
Current scope:
507+
508+
- file path evaluation
509+
- command cwd evaluation
510+
- heuristic detection of obvious path-like command arguments
511+
- native backend-side deny enforcement
512+
513+
Current limit:
514+
515+
- it is not a full shell parser
516+
- it does not automatically wire itself through every integration seam yet
517+
518+
Primary references:
519+
520+
- [Host Backends and Projections](https://vcoderun.github.io/acpkit/host-backends/)
521+
- [Projection Cookbook](https://vcoderun.github.io/acpkit/projection-cookbook/)
522+
523+
## Black-box Integration Harness
524+
525+
`BlackBoxHarness` exists so downstream integrations can prove the ACP boundary without rebuilding test plumbing from scratch.
526+
527+
Reach for it when the integration already "works" but still lacks proof for:
528+
529+
- approval replay
530+
- host-backed side effects
531+
- session reload correctness
532+
- ACP-visible transcript truthfulness
533+
534+
Use it:
535+
536+
- after the integration already has a real adapter construction seam
537+
- when you need one reusable way to drive approvals, prompts, reloads, and visible updates
538+
- when a normal unit test would miss ACP-visible behavior
539+
540+
Do not use it:
541+
542+
- to inspect private helper ordering
543+
- as a substitute for product-level end-to-end testing
544+
- before the integration has a coherent ownership model for sessions, approvals, and host tools
545+
546+
Use it when you want to verify:
547+
548+
- session create/load behavior
549+
- visible ACP updates
550+
- approval roundtrips
551+
- host-backed file or terminal flows
552+
- replay after reload
553+
554+
What it gives you:
555+
556+
- adapter construction plus a recording ACP client in one object
557+
- `new_session(...)`
558+
- `load_session(...)`
559+
- `prompt_text(...)`
560+
- `set_mode(...)`
561+
- `set_model(...)`
562+
- permission response queueing helpers
563+
- update filtering
564+
- reconstructed agent messages
565+
566+
Typical use:
567+
568+
```python
569+
import asyncio
570+
571+
from pydantic_acp import AdapterConfig, BlackBoxHarness, FileSessionStore
572+
573+
harness = BlackBoxHarness.create(
574+
agent_factory=build_agent,
575+
config=AdapterConfig(session_store=FileSessionStore(tmp_path / 'sessions')),
576+
)
577+
578+
session = asyncio.run(harness.new_session(cwd=str(tmp_path)))
579+
harness.queue_permission_selected('allow_once')
580+
response = asyncio.run(harness.prompt_text('Write the workspace note.'))
581+
582+
assert response.stop_reason == 'end_turn'
583+
assert harness.tool_updates(session_id=session.session_id)
584+
assert harness.agent_messages(session_id=session.session_id)
585+
```
586+
587+
Small verified example from the harness test shape:
588+
589+
```python
590+
session = asyncio.run(harness.new_session(cwd=str(tmp_path)))
591+
harness.queue_permission_selected('allow_once')
592+
response = asyncio.run(harness.prompt_text('Write the workspace note.'))
593+
594+
assert response.stop_reason == 'end_turn'
595+
assert harness.agent_messages(session_id=session.session_id) == ['done']
596+
```
597+
598+
The harness is intentionally black-box.
599+
600+
Prefer asserting on:
601+
602+
- ACP return values
603+
- emitted `ToolCallStart` / `ToolCallProgress` updates
604+
- reconstructed visible messages
605+
- persisted replay behavior
606+
- real host-backed side effects
607+
608+
Do not use it to:
609+
610+
- inspect private helper choreography
611+
- lock internal runtime call order
612+
- replace product-level end-to-end tests
613+
614+
Good default scenario ladder for a new integration:
615+
616+
1. session create -> prompt -> reload
617+
2. approval required -> allow once
618+
3. approval required -> deny once
619+
4. host-backed file read/write
620+
5. host-backed terminal execution
621+
6. mode switch changes behavior
622+
7. model switch changes session-local state
623+
624+
Primary references:
625+
626+
- [Integration Testing](https://vcoderun.github.io/acpkit/integration-testing/)
627+
- [Examples Overview](https://vcoderun.github.io/acpkit/examples/)
628+
420629
## Projection Maps And Hook Rendering
421630

422631
Projection maps make ACP clients see richer file or command behavior than a raw generic tool card.
@@ -430,6 +639,30 @@ Common maps:
430639
Use them when the client should see more structured output, but avoid pretending a tool is
431640
something it is not.
432641

642+
### Projection Helper Primitives
643+
644+
ACP Kit now also ships small reusable projection helpers for integrations that need consistent shaping but do not want to rebuild truncation and warning logic repeatedly.
645+
646+
High-value helpers:
647+
648+
- `truncate_text(...)`
649+
- `truncate_lines(...)`
650+
- `single_line_summary(...)`
651+
- `format_code_block(...)`
652+
- `format_diff_preview(...)`
653+
- `format_terminal_status(...)`
654+
- `caution_for_path(...)`
655+
- `caution_for_command(...)`
656+
657+
Use these helpers when:
658+
659+
- a chat client needs a plain-text diff preview
660+
- command titles should stay compact and consistent
661+
- long stdout/stderr content needs predictable truncation
662+
- caution text should come from the same `HostAccessPolicy` evaluation model as backend enforcement
663+
664+
These helpers are intentionally small. They are building blocks, not a full rendering framework.
665+
433666
## Examples That Matter
434667

435668
High-value maintained examples live under `examples/pydantic/`:
@@ -470,10 +703,101 @@ High-value docs pages:
470703
- [Providers](https://vcoderun.github.io/acpkit/providers/)
471704
- [Bridges](https://vcoderun.github.io/acpkit/bridges/)
472705
- [Host Backends and Projections](https://vcoderun.github.io/acpkit/host-backends/)
706+
- [Integration Testing](https://vcoderun.github.io/acpkit/integration-testing/)
707+
- [Projection Cookbook](https://vcoderun.github.io/acpkit/projection-cookbook/)
473708
- [Examples Overview](https://vcoderun.github.io/acpkit/examples/)
474709
- [Workspace Agent](https://vcoderun.github.io/acpkit/examples/workspace-agent/)
475710
- [pydantic_acp API](https://vcoderun.github.io/acpkit/api/pydantic_acp/)
476711

712+
## Compatibility Manifest
713+
714+
ACP Kit now also ships a typed root-level compatibility manifest schema through `acpkit`.
715+
716+
Reach for it after the integration already has real seams and at least one black-box proof path.
717+
718+
Do not use it as a speculative roadmap scratchpad. Use it as a reviewable declaration of what is actually wired today.
719+
720+
Use it:
721+
722+
- after at least one black-box proof path exists
723+
- when reviews need one typed declaration of supported ACP surfaces
724+
- when docs should be generated from validated code instead of prose drift
725+
726+
Do not use it:
727+
728+
- before the integration can already demonstrate the behavior it claims
729+
- as a replacement for proof tests
730+
- as a vague backlog matrix with no mapping seam
731+
732+
Use it when a real integration needs one reviewable declaration of:
733+
734+
- which ACP surfaces are implemented
735+
- which are partial
736+
- which are intentionally not used
737+
- which are only planned
738+
739+
Core types:
740+
741+
- `CompatibilityManifest`
742+
- `SurfaceSupport`
743+
- `SurfaceStatus`
744+
- `SurfaceOwner`
745+
746+
Typical use:
747+
748+
```python
749+
from acpkit import CompatibilityManifest, SurfaceSupport
750+
751+
manifest = CompatibilityManifest(
752+
integration_name='workspace-agent',
753+
adapter='pydantic-acp',
754+
surfaces={
755+
'session.load': SurfaceSupport(
756+
status='implemented',
757+
owner='adapter',
758+
mapping='FileSessionStore + load_session',
759+
),
760+
'mode.switch': SurfaceSupport(
761+
status='partial',
762+
owner='bridge',
763+
mapping='PrepareToolsBridge dynamic modes',
764+
rationale='Only explicitly exposed runtime modes are surfaced.',
765+
),
766+
'authenticate': SurfaceSupport(
767+
status='planned',
768+
rationale='No auth handshake has been added yet.',
769+
),
770+
},
771+
)
772+
773+
manifest.validate()
774+
```
775+
776+
Minimal review rule:
777+
778+
- every `implemented` surface should point to one concrete mapping seam
779+
- every `partial`, `intentionally_not_used`, and `planned` surface should explain why
780+
- `mixed` ownership is only acceptable when the split is named explicitly
781+
782+
Important rule:
783+
784+
- do not generate this from guesses
785+
- derive it from a real integration audit
786+
- then validate it in tests
787+
788+
Recommended workflow:
789+
790+
1. inventory real seams
791+
2. declare surfaces in code
792+
3. call `manifest.validate()` in tests or CI
793+
4. optionally publish `manifest.to_markdown()` into docs
794+
795+
This is not a runtime feature. It is an integration review and documentation hygiene feature.
796+
797+
Primary reference:
798+
799+
- [Compatibility Manifest Guide](https://vcoderun.github.io/acpkit/compatibility-matrix-template/)
800+
477801
## Skill-Local Routing Aids
478802

479803
These files exist to route you quickly into the right part of the codebase or docs set when the
@@ -499,6 +823,7 @@ Use the bundled scripts instead of guessing:
499823
- Keep examples runnable, explicit, and strongly typed.
500824
- Treat adapter-owned state and host-owned state as different design choices.
501825
- Prefer the narrowest seam that matches the user’s need.
826+
- Use the compatibility manifest when an integration needs one typed, reviewable ACP surface declaration instead of a loose prose matrix.
502827
- `FileSessionStore` uses `root=Path(...)`.
503828
- `FileSessionStore` is the hardened local durable store, not a distributed session backend.
504829
- Mode slash commands are dynamic, and mode ids must not collide with reserved names such as `model`, `thinking`, `tools`, `hooks`, or `mcp-servers`.

0 commit comments

Comments
 (0)