@octane-xplat/mcp 0.1.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +338 -1
- package/package.json +37 -4
- package/src/actions/bridge.mjs +2 -0
- package/src/contracts/actions.d.ts +209 -0
- package/src/contracts/actions.mjs +3 -0
- package/src/contracts/boundaries.d.ts +6 -0
- package/src/contracts/boundaries.mjs +3 -0
- package/src/contracts/capabilities.d.ts +106 -0
- package/src/contracts/capabilities.mjs +3 -0
- package/src/contracts/code.d.ts +134 -0
- package/src/contracts/code.mjs +3 -0
- package/src/contracts/errors.d.ts +75 -0
- package/src/contracts/errors.mjs +3 -0
- package/src/contracts/evidence.d.ts +115 -0
- package/src/contracts/evidence.mjs +3 -0
- package/src/contracts/identity.d.ts +127 -0
- package/src/contracts/identity.mjs +3 -0
- package/src/contracts/index.d.ts +11 -0
- package/src/contracts/index.mjs +3 -0
- package/src/contracts/inspection.d.ts +45 -0
- package/src/contracts/inspection.mjs +3 -0
- package/src/contracts/policy.d.ts +86 -0
- package/src/contracts/policy.mjs +3 -0
- package/src/contracts/sessions.d.ts +160 -0
- package/src/contracts/sessions.mjs +3 -0
- package/src/contracts/status.d.ts +40 -0
- package/src/contracts/status.mjs +3 -0
- package/src/discovery.mjs +2 -0
- package/src/docs.mjs +84 -0
- package/src/inspection/service.mjs +5 -0
- package/src/inspection/tools.mjs +53 -0
- package/src/runtime/logs.mjs +2 -0
- package/src/runtime/process.mjs +2 -0
- package/src/runtime/service.mjs +2 -0
- package/src/runtime/targets.mjs +2 -0
- package/src/runtime/tools.mjs +126 -0
- package/src/server.mjs +565 -0
- package/src/status.mjs +2 -0
- package/src/xplat-mcp.mjs +85 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explicit capability matrix — per platform and target, each capability is
|
|
3
|
+
* reported separately. Unsupported or unqualified capabilities stay visible
|
|
4
|
+
* with an explanation and a usable alternative, never hidden or faked.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AppRef, Platform, RuntimePrerequisite } from './identity'
|
|
8
|
+
import type { PermissionScope } from './policy'
|
|
9
|
+
|
|
10
|
+
/** The externally observable capability surface. */
|
|
11
|
+
export const CAPABILITY_IDS: readonly CapabilityId[]
|
|
12
|
+
|
|
13
|
+
export type CapabilityId =
|
|
14
|
+
/** Detected project identity, versions, guidance, prerequisites (package A). */
|
|
15
|
+
| 'project_status'
|
|
16
|
+
/** Project-scoped guidance retrieval. */
|
|
17
|
+
| 'guidance'
|
|
18
|
+
/** Version-bound documentation search/read (package B). */
|
|
19
|
+
| 'docs'
|
|
20
|
+
/** Exact/semantic code discovery (package C). */
|
|
21
|
+
| 'code_search'
|
|
22
|
+
/** Device/target enumeration with availability and ownership (package D). */
|
|
23
|
+
| 'target_discovery'
|
|
24
|
+
/** Authorized build for a development session (package D). */
|
|
25
|
+
| 'build'
|
|
26
|
+
/** Launch a built app on a target (package D). */
|
|
27
|
+
| 'launch'
|
|
28
|
+
/** Attach to an existing compatible development session (package D). */
|
|
29
|
+
| 'attach'
|
|
30
|
+
/** Bounded, cursor-paginated logs with gap indicators (package D). */
|
|
31
|
+
| 'logs'
|
|
32
|
+
/** Job status/cancellation without holding a tool call open (package A+D). */
|
|
33
|
+
| 'job_control'
|
|
34
|
+
/** Qualified host-state inspection (package E). */
|
|
35
|
+
| 'ui_inspection'
|
|
36
|
+
/** Screenshot capture — always permission-gated at action time (package E). */
|
|
37
|
+
| 'screenshot'
|
|
38
|
+
/** Scoped interactions with an explicit mechanism (package E). */
|
|
39
|
+
| 'interaction'
|
|
40
|
+
/** App-declared development actions: discovery + invocation (package G). */
|
|
41
|
+
| 'dev_actions'
|
|
42
|
+
/** Ownership-safe session end (package A+D). */
|
|
43
|
+
| 'session_end'
|
|
44
|
+
/** Session-scoped evidence with retain/delete (package A). */
|
|
45
|
+
| 'evidence'
|
|
46
|
+
|
|
47
|
+
export type CapabilityStatus =
|
|
48
|
+
/** Usable now on this platform/target. */
|
|
49
|
+
| 'supported'
|
|
50
|
+
/** Works within stated coverage limits; `detail` names them. */
|
|
51
|
+
| 'partial'
|
|
52
|
+
/** Exists, but every use is checked against a permission grant at action time. */
|
|
53
|
+
| 'permission_gated'
|
|
54
|
+
/** Achievable on this platform but a provider or prerequisite is absent. */
|
|
55
|
+
| 'unavailable'
|
|
56
|
+
/** Not possible on this platform; `detail` says why. */
|
|
57
|
+
| 'unsupported'
|
|
58
|
+
/** Not yet qualified; never presented as ready. */
|
|
59
|
+
| 'unknown'
|
|
60
|
+
|
|
61
|
+
/** A usable path when a capability is not supported here. */
|
|
62
|
+
export interface CapabilityAlternative {
|
|
63
|
+
description: string
|
|
64
|
+
/** A concrete command the developer can run, when one exists. */
|
|
65
|
+
command?: string
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface CapabilityEntry {
|
|
69
|
+
capability: CapabilityId
|
|
70
|
+
status: CapabilityStatus
|
|
71
|
+
/** Why the capability is limited, missing, or gated — or its coverage bounds. */
|
|
72
|
+
detail?: string
|
|
73
|
+
/** The grant checked at action time (screenshots: 'visual-capture'). */
|
|
74
|
+
requiresPermission?: PermissionScope
|
|
75
|
+
prerequisites?: RuntimePrerequisite[]
|
|
76
|
+
alternative?: CapabilityAlternative
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface PlatformCapabilityMatrix {
|
|
80
|
+
platform: Platform
|
|
81
|
+
/** Whether the bound app declares this platform. */
|
|
82
|
+
declared: boolean
|
|
83
|
+
capabilities: CapabilityEntry[]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A platform adapter supplied by a runtime package (D/E/G). Providers return
|
|
88
|
+
* entries only for capabilities they implement; everything else keeps the
|
|
89
|
+
* honest default from `defaultCapabilityEntry`.
|
|
90
|
+
*/
|
|
91
|
+
export interface CapabilityProvider {
|
|
92
|
+
platform: Platform
|
|
93
|
+
describe(app: AppRef): CapabilityEntry[] | Promise<CapabilityEntry[]>
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export declare function defaultCapabilityEntry(
|
|
97
|
+
capability: CapabilityId,
|
|
98
|
+
platform: Platform,
|
|
99
|
+
): CapabilityEntry
|
|
100
|
+
|
|
101
|
+
export interface CapabilityRegistry {
|
|
102
|
+
register(provider: CapabilityProvider): void
|
|
103
|
+
matrixFor(app: AppRef | null, platforms: Platform[]): Promise<PlatformCapabilityMatrix[]>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export declare function createCapabilityRegistry(): CapabilityRegistry
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code retrieval contract (work item C) — the provider seam the workspace
|
|
3
|
+
* context's `code` slot and the `xplat_code_search` / `xplat_code_read` tools
|
|
4
|
+
* consume.
|
|
5
|
+
*
|
|
6
|
+
* Rules carried by the design:
|
|
7
|
+
* - Exact search reads current source files directly — it stays usable while
|
|
8
|
+
* the semantic index is absent, preparing, stale, or failed.
|
|
9
|
+
* - Semantic search is optional local acceleration (no remote embedding
|
|
10
|
+
* without explicit opt-in). Similarity rank is relevance, never evidence of
|
|
11
|
+
* correctness or platform support.
|
|
12
|
+
* - Results are leads: every hit carries a ref, provenance, and a freshness
|
|
13
|
+
* marker so the agent can open current source before citing an API.
|
|
14
|
+
* - Secrets, private configuration, generated output, and paths outside the
|
|
15
|
+
* permitted corpus scope are never served.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { AppRef, Platform, SubsystemState, WorkspaceKind } from './identity'
|
|
19
|
+
|
|
20
|
+
/** `app` = the bound application's own source; `framework` = its installed @octane-xplat package sources. */
|
|
21
|
+
export type CodeCorpus = 'app' | 'framework'
|
|
22
|
+
|
|
23
|
+
export type CodeSearchMode = 'auto' | 'exact' | 'semantic'
|
|
24
|
+
|
|
25
|
+
/** Per-hit freshness: `current` means revalidated or read live just now. */
|
|
26
|
+
export interface CodeFreshness {
|
|
27
|
+
state: 'current' | 'stale'
|
|
28
|
+
/** Content hash at serve time — a later read with a different hash drifted. */
|
|
29
|
+
contentHash?: string
|
|
30
|
+
mtimeMs?: number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface CodeHitProvenance {
|
|
34
|
+
source: 'app-source' | 'framework-source'
|
|
35
|
+
scope: 'release' | 'project'
|
|
36
|
+
package?: string | null
|
|
37
|
+
requestedVersion?: string | null
|
|
38
|
+
servedVersion?: string | null
|
|
39
|
+
match:
|
|
40
|
+
| 'exact'
|
|
41
|
+
| 'verified-compatible'
|
|
42
|
+
| 'outside-installed-binding'
|
|
43
|
+
| 'unavailable'
|
|
44
|
+
| 'tag-conflict'
|
|
45
|
+
offline?: boolean
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface CodeHit {
|
|
49
|
+
/** `xplat-code://<corpus>/<key>` — open it with xplat_code_read. */
|
|
50
|
+
ref: string
|
|
51
|
+
corpus: CodeCorpus
|
|
52
|
+
package?: string
|
|
53
|
+
/** Corpus-relative path (app: workspace-relative; framework: package source root). */
|
|
54
|
+
path: string
|
|
55
|
+
line: number
|
|
56
|
+
endLine: number
|
|
57
|
+
excerpt: string
|
|
58
|
+
matchType: 'exact' | 'semantic'
|
|
59
|
+
score?: number
|
|
60
|
+
freshness: CodeFreshness
|
|
61
|
+
provenance: CodeHitProvenance
|
|
62
|
+
/** Index revision that produced a semantic hit. */
|
|
63
|
+
indexRevision?: number
|
|
64
|
+
provisional?: boolean
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface SemanticIndexStatus {
|
|
68
|
+
state: SubsystemState
|
|
69
|
+
/** e.g. 'local-tfidf' — remote embedding is never used without opt-in. */
|
|
70
|
+
backend?: string
|
|
71
|
+
detail?: string
|
|
72
|
+
files?: number
|
|
73
|
+
chunks?: number
|
|
74
|
+
truncated?: boolean
|
|
75
|
+
revision?: number
|
|
76
|
+
/** Hits dropped because they failed revalidation against current source. */
|
|
77
|
+
droppedStale?: number
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface CodeSearchArgs {
|
|
81
|
+
app: AppRef | null
|
|
82
|
+
workspaceKind?: WorkspaceKind
|
|
83
|
+
query: string
|
|
84
|
+
mode?: CodeSearchMode
|
|
85
|
+
corpus?: CodeCorpus | 'all'
|
|
86
|
+
platform?: Platform
|
|
87
|
+
package?: string
|
|
88
|
+
limit?: number
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface CodeSearchResult {
|
|
92
|
+
status?: CodeResultStatus
|
|
93
|
+
mode: CodeSearchMode
|
|
94
|
+
results: CodeHit[]
|
|
95
|
+
semantic: SemanticIndexStatus
|
|
96
|
+
coverage: unknown
|
|
97
|
+
/** Working-tree freshness marker (HEAD + uncommitted count) when git is available. */
|
|
98
|
+
tree?: string
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface CodeReadArgs {
|
|
102
|
+
app: AppRef | null
|
|
103
|
+
workspaceKind?: WorkspaceKind
|
|
104
|
+
ref?: string
|
|
105
|
+
corpus?: CodeCorpus
|
|
106
|
+
package?: string
|
|
107
|
+
path?: string
|
|
108
|
+
offset?: number
|
|
109
|
+
limit?: number
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type CodeResultStatus =
|
|
113
|
+
| 'selection-required'
|
|
114
|
+
| 'invalid-selection'
|
|
115
|
+
| 'invalid-ref'
|
|
116
|
+
| 'out-of-scope'
|
|
117
|
+
| 'excluded'
|
|
118
|
+
| 'unavailable'
|
|
119
|
+
|
|
120
|
+
export interface CodeErrorResult {
|
|
121
|
+
status: CodeResultStatus
|
|
122
|
+
reason?: string
|
|
123
|
+
detail?: string
|
|
124
|
+
corpus?: string
|
|
125
|
+
path?: string
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** The provider contract injected as `options.code` on the workspace context. */
|
|
129
|
+
export interface CodeProvider {
|
|
130
|
+
/** Fills the project-status `codeIndex` slot. */
|
|
131
|
+
status(app: AppRef | null): unknown
|
|
132
|
+
search(args: CodeSearchArgs): CodeSearchResult | CodeErrorResult | Promise<unknown>
|
|
133
|
+
read(args: CodeReadArgs): unknown | Promise<unknown>
|
|
134
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared error vocabulary for the Octane Xplat MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Every tool failure is one of these codes — agents must be able to tell an
|
|
5
|
+
* invalid selection from a missing prerequisite, a busy target, a stale
|
|
6
|
+
* identity, a disconnected runtime, or a real execution failure. Each error
|
|
7
|
+
* names the smallest corrective action through `recovery`.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const CONTRACT_ERROR_CODES: readonly ContractErrorCode[]
|
|
11
|
+
|
|
12
|
+
export type ContractErrorCode =
|
|
13
|
+
/** The named app, target, session, job, or option does not exist or does not apply. */
|
|
14
|
+
| 'invalid_selection'
|
|
15
|
+
/** Equally plausible choices would change the result — the developer must pick. Never resolved silently. */
|
|
16
|
+
| 'ambiguous_selection'
|
|
17
|
+
/** A required permission grant is absent, expired, or revoked. */
|
|
18
|
+
| 'permission_denied'
|
|
19
|
+
/** The platform/target does not support this capability; `alternative` may offer a usable path. */
|
|
20
|
+
| 'unsupported_capability'
|
|
21
|
+
/** A toolchain, device, or data prerequisite is missing; `recovery` names the smallest fix. */
|
|
22
|
+
| 'prerequisite_missing'
|
|
23
|
+
/** The target is owned by another session/agent, or a bounded queue is saturated. */
|
|
24
|
+
| 'target_busy'
|
|
25
|
+
/** The session, registry revision, or build identity changed since the caller bound it. */
|
|
26
|
+
| 'stale_identity'
|
|
27
|
+
/** The runtime disconnected; last-known state is historical evidence, never current state. */
|
|
28
|
+
| 'disconnected_runtime'
|
|
29
|
+
/** The operation ran and failed. */
|
|
30
|
+
| 'execution_failure'
|
|
31
|
+
/** The named resource (job, session, evidence record) does not exist. */
|
|
32
|
+
| 'not_found'
|
|
33
|
+
/** Cancellation won the race or was requested before/while running. */
|
|
34
|
+
| 'cancelled'
|
|
35
|
+
/** A bounded wait or execution timeout expired. */
|
|
36
|
+
| 'timeout'
|
|
37
|
+
/** An optional subsystem (docs index, code index, embeddings) is not provided or offline. */
|
|
38
|
+
| 'unavailable'
|
|
39
|
+
|
|
40
|
+
/** The smallest corrective step a developer or agent can take. */
|
|
41
|
+
export interface Recovery {
|
|
42
|
+
/** Imperative description, e.g. "Select an app with xplat_select_app". */
|
|
43
|
+
action: string
|
|
44
|
+
/** Optional concrete detail: a command, path, or env var. */
|
|
45
|
+
detail?: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface ContractError {
|
|
49
|
+
code: ContractErrorCode
|
|
50
|
+
message: string
|
|
51
|
+
recovery?: Recovery
|
|
52
|
+
/** Whether retrying the same call could succeed without other changes. */
|
|
53
|
+
retryable?: boolean
|
|
54
|
+
/** Structured context, e.g. `candidates` for ambiguous_selection. */
|
|
55
|
+
context?: Record<string, unknown>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Success/failure envelope used by every MCP tool result's structuredContent. */
|
|
59
|
+
export type ToolOutcome<T> = { ok: true; data: T } | { ok: false; error: ContractError }
|
|
60
|
+
|
|
61
|
+
export declare function contractError(
|
|
62
|
+
code: ContractErrorCode,
|
|
63
|
+
message: string,
|
|
64
|
+
options?: { recovery?: Recovery; retryable?: boolean; context?: Record<string, unknown> },
|
|
65
|
+
): ContractError
|
|
66
|
+
|
|
67
|
+
export declare function ok<T>(data: T): ToolOutcome<T>
|
|
68
|
+
export declare function fail(error: ContractError): ToolOutcome<never>
|
|
69
|
+
export declare function isContractError(value: unknown): value is ContractError
|
|
70
|
+
|
|
71
|
+
/** Normalize any thrown value into a ContractError (default code: execution_failure). */
|
|
72
|
+
export declare function toContractError(
|
|
73
|
+
value: unknown,
|
|
74
|
+
fallbackCode?: ContractErrorCode,
|
|
75
|
+
): ContractError
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence and retention contract.
|
|
3
|
+
*
|
|
4
|
+
* Evidence is session-scoped by default: when the MCP session ends, its
|
|
5
|
+
* artifacts are deleted. The developer may explicitly retain selected
|
|
6
|
+
* artifacts with a stated expiration or until manual deletion, and may delete
|
|
7
|
+
* retained evidence sooner. Deleting server artifacts cannot erase an
|
|
8
|
+
* external agent-client transcript that recorded them — that note travels
|
|
9
|
+
* with every retain/delete result (`TRANSCRIPT_LIMITATION_NOTE`).
|
|
10
|
+
*
|
|
11
|
+
* Every observation carries provenance: app, platform, target, session,
|
|
12
|
+
* build/source identity, capture time, and — for interactions — the
|
|
13
|
+
* mechanism. `handler-dispatch` and `dom-event` evidence must never be
|
|
14
|
+
* presented as OS-input verification (`isOsInputEvidence`).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { BuildIdentity } from './sessions'
|
|
18
|
+
import type { Platform } from './identity'
|
|
19
|
+
import type { ContractError } from './errors'
|
|
20
|
+
|
|
21
|
+
export const EVIDENCE_KINDS: readonly EvidenceKind[]
|
|
22
|
+
export const INTERACTION_MECHANISMS: readonly InteractionMechanism[]
|
|
23
|
+
/** Included in retain/delete results: deletion here never touches the client transcript. */
|
|
24
|
+
export const TRANSCRIPT_LIMITATION_NOTE: string
|
|
25
|
+
|
|
26
|
+
export type EvidenceKind =
|
|
27
|
+
| 'log'
|
|
28
|
+
| 'screenshot'
|
|
29
|
+
| 'inspection'
|
|
30
|
+
| 'interaction'
|
|
31
|
+
| 'measurement'
|
|
32
|
+
| 'assertion'
|
|
33
|
+
| 'job'
|
|
34
|
+
| 'note'
|
|
35
|
+
|
|
36
|
+
export type InteractionMechanism =
|
|
37
|
+
/** App handler invoked directly — proves handler behavior only. */
|
|
38
|
+
| 'handler-dispatch'
|
|
39
|
+
/** Synthesized DOM/platform events — proves event-path behavior, not OS hit-testing. */
|
|
40
|
+
| 'dom-event'
|
|
41
|
+
/** Real OS input path — can support OS-level claims. */
|
|
42
|
+
| 'os-input'
|
|
43
|
+
/** Not an interaction record. */
|
|
44
|
+
| 'none'
|
|
45
|
+
|
|
46
|
+
export interface EvidenceProvenance {
|
|
47
|
+
appId?: string
|
|
48
|
+
platform?: Platform
|
|
49
|
+
targetId?: string
|
|
50
|
+
sessionId?: string
|
|
51
|
+
buildIdentity?: BuildIdentity
|
|
52
|
+
/** ISO capture time. */
|
|
53
|
+
capturedAt: string
|
|
54
|
+
mechanism?: InteractionMechanism
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type EvidenceRetention =
|
|
58
|
+
/** Deleted when the MCP session ends (the default). */
|
|
59
|
+
| { scope: 'session' }
|
|
60
|
+
/** Kept until `expiresAt` (null = until manual deletion). */
|
|
61
|
+
| { scope: 'retained'; expiresAt: string | null }
|
|
62
|
+
|
|
63
|
+
export interface EvidenceRecord {
|
|
64
|
+
id: string
|
|
65
|
+
kind: EvidenceKind
|
|
66
|
+
summary: string
|
|
67
|
+
provenance: EvidenceProvenance
|
|
68
|
+
/** File path under the evidence root, for binary/large artifacts. */
|
|
69
|
+
artifactPath?: string
|
|
70
|
+
/** Small structured payload kept in memory. */
|
|
71
|
+
data?: unknown
|
|
72
|
+
retention: EvidenceRetention
|
|
73
|
+
createdAt: string
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface RetainResult {
|
|
77
|
+
record: EvidenceRecord
|
|
78
|
+
transcriptNote: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface DeleteResult {
|
|
82
|
+
deleted: boolean
|
|
83
|
+
transcriptNote: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface EvidenceStore {
|
|
87
|
+
record(input: {
|
|
88
|
+
kind: EvidenceKind
|
|
89
|
+
summary: string
|
|
90
|
+
provenance: Omit<EvidenceProvenance, 'capturedAt'> & { capturedAt?: string }
|
|
91
|
+
data?: unknown
|
|
92
|
+
/** Write this content as the artifact file (utf8). */
|
|
93
|
+
artifact?: string | Uint8Array
|
|
94
|
+
/** Suggested artifact file name; sanitized. */
|
|
95
|
+
artifactName?: string
|
|
96
|
+
}): EvidenceRecord
|
|
97
|
+
list(filter?: { sessionId?: string; kind?: EvidenceKind }): EvidenceRecord[]
|
|
98
|
+
/** Move a record out of session scope. `expiresAt` ISO string or null for manual deletion. */
|
|
99
|
+
retain(
|
|
100
|
+
id: string,
|
|
101
|
+
options?: { expiresAt?: string | null },
|
|
102
|
+
): RetainResult | { error: ContractError }
|
|
103
|
+
delete(id: string): DeleteResult | { error: ContractError }
|
|
104
|
+
/** Delete retained records past their expiration. */
|
|
105
|
+
sweepExpired(now?: Date): number
|
|
106
|
+
/** Session end: delete every session-scoped record and its artifact file. */
|
|
107
|
+
closeSession(): { deleted: number }
|
|
108
|
+
/** Absolute path of the evidence root for this server session. */
|
|
109
|
+
readonly root: string
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** True only for evidence captured through the real OS input path. */
|
|
113
|
+
export declare function isOsInputEvidence(record: EvidenceRecord): boolean
|
|
114
|
+
|
|
115
|
+
export declare function createEvidenceStore(options: { root: string }): EvidenceStore
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project identity contract — what the server detects and reports about the
|
|
3
|
+
* developer's workspace during setup, and the shape of the project-status
|
|
4
|
+
* report every later package (docs, code, runtime) plugs into.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export const PLATFORMS: readonly Platform[]
|
|
8
|
+
|
|
9
|
+
/** The six release-boundary targets. `web` means Chromium acceptance checks. */
|
|
10
|
+
export type Platform = 'web' | 'ios' | 'android' | 'macos' | 'linux' | 'windows'
|
|
11
|
+
|
|
12
|
+
/** A detected application inside the selected workspace. */
|
|
13
|
+
export interface AppRef {
|
|
14
|
+
/** Stable identity for selection and binding: workspace-relative root path ('.' for the root app). */
|
|
15
|
+
id: string
|
|
16
|
+
/** package.json name, falling back to the directory basename. */
|
|
17
|
+
name: string
|
|
18
|
+
/** Absolute path. */
|
|
19
|
+
root: string
|
|
20
|
+
/** Path relative to the workspace root. */
|
|
21
|
+
relativeRoot: string
|
|
22
|
+
/**
|
|
23
|
+
* `consumer-app` — a deployable Octane Xplat application (the primary setup path).
|
|
24
|
+
* `framework-package` — a package inside the octane-xplat framework repository
|
|
25
|
+
* (identified separately, never silently treated as the consumer app).
|
|
26
|
+
*/
|
|
27
|
+
kind: 'consumer-app' | 'framework-package'
|
|
28
|
+
/** Platforms this app declares (from its config and dependencies). */
|
|
29
|
+
platforms: Platform[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Where a package version came from. `installed` is the only version that binds docs. */
|
|
33
|
+
export type VersionSource = 'installed' | 'workspace' | 'lockfile' | 'unresolved'
|
|
34
|
+
|
|
35
|
+
export interface PackageVersion {
|
|
36
|
+
/** e.g. `@octane-xplat/ui`. */
|
|
37
|
+
name: string
|
|
38
|
+
version: string | null
|
|
39
|
+
source: VersionSource
|
|
40
|
+
/** The declared range in the app's manifest, when it differs from the resolved version. */
|
|
41
|
+
declared?: string
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface FrameworkBinding {
|
|
45
|
+
packages: PackageVersion[]
|
|
46
|
+
/**
|
|
47
|
+
* `installed` — resolved from the app's actual node_modules (binds documentation).
|
|
48
|
+
* `provisional` — lockfile/declared only; the real install could not be verified.
|
|
49
|
+
* `unresolved` — no version information at all.
|
|
50
|
+
*/
|
|
51
|
+
status: 'installed' | 'provisional' | 'unresolved'
|
|
52
|
+
/** Set when the lockfile and the actual installation disagree; installation wins. */
|
|
53
|
+
discrepancy?: string
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface GuidanceSource {
|
|
57
|
+
kind: 'agents-md' | 'claude-md' | 'devin' | 'framework' | 'other'
|
|
58
|
+
/** Workspace-relative path. */
|
|
59
|
+
path: string
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Project-level guidance the agent should read; never mixed into generic docs results. */
|
|
63
|
+
export interface GuidanceStatus {
|
|
64
|
+
sources: GuidanceSource[]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Optional-subsystem readiness. `not_provided` = no provider registered yet. */
|
|
68
|
+
export type SubsystemState = 'ready' | 'preparing' | 'stale' | 'unavailable' | 'not_provided'
|
|
69
|
+
|
|
70
|
+
export interface DocsStatus {
|
|
71
|
+
state: SubsystemState
|
|
72
|
+
/** e.g. which version binding is active, or why docs are unavailable. */
|
|
73
|
+
detail?: string
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface CodeIndexStatus {
|
|
77
|
+
state: SubsystemState
|
|
78
|
+
detail?: string
|
|
79
|
+
/** Human-readable freshness marker (index revision vs working tree). */
|
|
80
|
+
freshness?: string
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type PrerequisiteStatus = 'satisfied' | 'missing' | 'unknown'
|
|
84
|
+
|
|
85
|
+
export interface RuntimePrerequisite {
|
|
86
|
+
/** Stable id: `node`, `git`, `pnpm`, `xcode`, `adb`, `nativescript-cli`, `chromium`, … */
|
|
87
|
+
id: string
|
|
88
|
+
name: string
|
|
89
|
+
status: PrerequisiteStatus
|
|
90
|
+
/** e.g. the found version, or where it was looked for. */
|
|
91
|
+
detail?: string
|
|
92
|
+
/** The smallest corrective action when missing/unknown. */
|
|
93
|
+
remedy?: string
|
|
94
|
+
/** Platforms this prerequisite gates; absent = server-wide. */
|
|
95
|
+
platforms?: Platform[]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The workspace as a whole. */
|
|
99
|
+
export type WorkspaceKind =
|
|
100
|
+
/** A consumer application workspace (single- or multi-app monorepo). */
|
|
101
|
+
| 'consumer'
|
|
102
|
+
/** The octane-xplat framework repository itself — framework sources are a separate corpus. */
|
|
103
|
+
| 'framework-repo'
|
|
104
|
+
/** No Octane Xplat app detected. */
|
|
105
|
+
| 'empty'
|
|
106
|
+
|
|
107
|
+
export interface WorkspaceInfo {
|
|
108
|
+
root: string
|
|
109
|
+
kind: WorkspaceKind
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* App selection state. `ambiguous` is a first-class state: the server never
|
|
114
|
+
* silently picks among multiple apps — the developer (via the agent) must choose.
|
|
115
|
+
*/
|
|
116
|
+
export type AppSelection =
|
|
117
|
+
| { state: 'bound'; app: AppRef; reason: 'explicit' | 'sole-app' | 'configured' | 'preference' }
|
|
118
|
+
| { state: 'ambiguous'; candidates: AppRef[] }
|
|
119
|
+
| { state: 'none'; reason: 'no-apps' | 'workspace-not-found' }
|
|
120
|
+
|
|
121
|
+
export interface ProjectIdentity {
|
|
122
|
+
workspace: WorkspaceInfo
|
|
123
|
+
apps: AppRef[]
|
|
124
|
+
selection: AppSelection
|
|
125
|
+
/** Framework versions for the bound app (null while selection is ambiguous/none). */
|
|
126
|
+
framework: FrameworkBinding | null
|
|
127
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './errors'
|
|
2
|
+
export * from './identity'
|
|
3
|
+
export * from './capabilities'
|
|
4
|
+
export * from './policy'
|
|
5
|
+
export * from './sessions'
|
|
6
|
+
export * from './evidence'
|
|
7
|
+
export * from './boundaries'
|
|
8
|
+
export * from './status'
|
|
9
|
+
export * from './code'
|
|
10
|
+
export * from './actions'
|
|
11
|
+
export * from './inspection'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { EvidenceRecord } from './evidence'
|
|
2
|
+
|
|
3
|
+
/** Qualified scope of Chromium inspection; never a universal component tree. */
|
|
4
|
+
export const CHROMIUM_INSPECTION_COVERAGE: string
|
|
5
|
+
|
|
6
|
+
/** Select exactly one named DOM host. Duplicate names fail rather than choosing the first. */
|
|
7
|
+
export interface StableControl {
|
|
8
|
+
kind: 'id' | 'testID'
|
|
9
|
+
name: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface InspectedHost {
|
|
13
|
+
id: string | null
|
|
14
|
+
testID: string | null
|
|
15
|
+
tag: string
|
|
16
|
+
role: string | null
|
|
17
|
+
/** Bounded to 500 characters; password and data-xplat-private hosts are redacted. */
|
|
18
|
+
text: string
|
|
19
|
+
value: string | null
|
|
20
|
+
checked: boolean | null
|
|
21
|
+
disabled: boolean
|
|
22
|
+
hidden: boolean
|
|
23
|
+
sensitive: boolean
|
|
24
|
+
focused: boolean
|
|
25
|
+
hitTarget: boolean
|
|
26
|
+
/** Main-document CSS pixels, relative to the viewport. */
|
|
27
|
+
frame: { x: number; y: number; width: number; height: number }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Returned by xplat_inspect; documentId must accompany subsequent interactions. */
|
|
31
|
+
export interface HostInspection {
|
|
32
|
+
documentId: string
|
|
33
|
+
controls: InspectedHost[]
|
|
34
|
+
coverage: string
|
|
35
|
+
limitations: string[]
|
|
36
|
+
total: number
|
|
37
|
+
nextOffset: number | null
|
|
38
|
+
evidence: EvidenceRecord
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Input submission proves delivery only; observe and assert the intended state separately. */
|
|
42
|
+
export interface HostInteraction extends HostInspection {
|
|
43
|
+
inputSent: true
|
|
44
|
+
assertion: string
|
|
45
|
+
}
|