@astrale-os/cli 1.0.0-beta.0 → 1.0.0-beta.2
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/README.md +7 -11
- package/dist/astrale.js +3769 -3549
- package/dist/public/connect-core.js +396 -392
- package/dist/public/keys/index.js +371 -378
- package/dist/public/paths/index.js +371 -378
- package/dist/types/lib/idp.d.ts +6 -0
- package/dist/types/lib/meta.d.ts +2 -2
- package/package.json +6 -4
- package/src/admin/binding.ts +168 -0
- package/src/admin/catalog/__tests__/client.test.ts +2 -2
- package/src/admin/catalog/client.ts +4 -9
- package/src/admin/instance/__tests__/client.test.ts +5 -3
- package/src/admin/instance/client.ts +9 -27
- package/src/commands/__tests__/auth-login.test.ts +54 -1
- package/src/commands/__tests__/call.test.ts +5 -1
- package/src/commands/__tests__/domain-install-operation.test.ts +23 -7
- package/src/commands/__tests__/domain-install-owned.test.ts +5 -1
- package/src/commands/__tests__/domain-list.test.ts +83 -4
- package/src/commands/__tests__/install-identity-override.test.ts +30 -19
- package/src/commands/__tests__/studio-descriptor.test.ts +22 -0
- package/src/commands/__tests__/update.test.ts +73 -0
- package/src/commands/domain/install.ts +11 -15
- package/src/commands/domain/list.ts +17 -12
- package/src/commands/studio.ts +20 -0
- package/src/commands/update.ts +39 -13
- package/src/connection/__tests__/errors.test.ts +16 -12
- package/src/connection/__tests__/exchange.test.ts +6 -5
- package/src/connection/exchange.ts +5 -4
- package/src/lib/__tests__/domain-publication.test.ts +144 -0
- package/src/lib/__tests__/idp-session.test.ts +22 -0
- package/src/lib/__tests__/idp.test.ts +2 -0
- package/src/lib/__tests__/instance.test.ts +6 -0
- package/src/lib/__tests__/studio-server-deps.test.ts +53 -16
- package/src/lib/__tests__/update.test.ts +12 -0
- package/src/lib/domain-publication.ts +102 -0
- package/src/lib/idp.ts +5 -1
- package/src/lib/instance.ts +6 -1
- package/src/lib/login-flow.ts +13 -3
- package/src/lib/meta.ts +2 -2
- package/src/lib/update.ts +4 -4
- package/src/program/__tests__/program.test.ts +1 -1
- package/studio/client/dist/assets/{elk-api-D2xgMJvi.js → elk-api-lwhFo7vB.js} +1 -1
- package/studio/client/dist/assets/index-B-c-smo9.js +8 -0
- package/studio/client/dist/assets/index-BckHuAWk.js +81 -0
- package/studio/client/dist/assets/index-C4aNQ6dz.css +1 -0
- package/studio/client/dist/index.html +2 -2
- package/studio/package.json +3 -1
- package/studio/server/agent/bridge/stdio.ts +8 -1
- package/studio/server/agent/conversation.test.ts +10 -5
- package/studio/server/agent/conversation.ts +56 -8
- package/studio/server/agent/harness/codex/loadout.ts +18 -21
- package/studio/server/agent/harness/gateway/config.ts +20 -18
- package/studio/server/agent/harness/selection.ts +9 -1
- package/studio/server/agent/prompts/system.ts +3 -2
- package/studio/server/agent/prompts/turn.ts +13 -4
- package/studio/server/agent/run/completion.ts +2 -2
- package/studio/server/agent/run/preparation.ts +6 -5
- package/studio/server/agent/run/transcript.test.ts +35 -1
- package/studio/server/agent/run/transcript.ts +169 -3
- package/studio/server/agent/run/usage.test.ts +24 -0
- package/studio/server/agent/run/usage.ts +26 -1
- package/studio/server/api/canvas.ts +44 -0
- package/studio/server/api/comments.ts +85 -0
- package/studio/server/api/context.ts +61 -0
- package/studio/server/api/deployment.ts +39 -0
- package/studio/server/api/documents.ts +55 -0
- package/studio/server/api/domain.ts +59 -0
- package/studio/server/api/http.ts +45 -0
- package/studio/server/api/project.ts +57 -0
- package/studio/server/api/schema.ts +12 -0
- package/studio/server/api/views.ts +57 -0
- package/studio/server/api/workspace.ts +60 -0
- package/studio/server/api.test.ts +147 -0
- package/studio/server/api.ts +20 -422
- package/studio/server/cache.test.ts +111 -0
- package/studio/server/cache.ts +163 -9
- package/studio/server/cli-consumers.test.ts +494 -0
- package/studio/server/cli.test.ts +88 -0
- package/studio/server/cli.ts +240 -0
- package/studio/server/client-package.ts +25 -1
- package/studio/server/domain.test.ts +30 -2
- package/studio/server/domain.ts +14 -2
- package/studio/server/environment/dotenv-preview.test.ts +39 -0
- package/studio/server/environment/dotenv-preview.ts +27 -0
- package/studio/server/environment/files.test.ts +53 -0
- package/studio/server/{state/env.ts → environment/files.ts} +7 -48
- package/studio/server/{state → handoff}/copy.ts +21 -6
- package/studio/server/handoff/service.test.ts +22 -0
- package/studio/server/{state/handoff.ts → handoff/service.ts} +21 -14
- package/studio/server/instances/active.ts +72 -0
- package/studio/server/instances/deploy-record.test.ts +31 -0
- package/studio/server/instances/deploy-record.ts +37 -0
- package/studio/server/instances/deploy.ts +56 -0
- package/studio/server/{state/instance.test.ts → instances/probe.test.ts} +25 -21
- package/studio/server/instances/probe.ts +67 -0
- package/studio/server/instances/status.test.ts +12 -0
- package/studio/server/instances/status.ts +49 -0
- package/studio/server/introspect/anatomy/client-tree.ts +57 -0
- package/studio/server/introspect/anatomy/env-fields.ts +66 -0
- package/studio/server/introspect/anatomy/schema-definition.ts +53 -0
- package/studio/server/introspect/anatomy/source.ts +181 -0
- package/studio/server/introspect/anatomy/views/legacy.ts +232 -0
- package/studio/server/introspect/anatomy/views/routes.ts +105 -0
- package/studio/server/introspect/anatomy/views.ts +58 -0
- package/studio/server/introspect/anatomy-extras.test.ts +91 -4
- package/studio/server/introspect/anatomy-extras.ts +7 -726
- package/studio/server/introspect/anatomy.ts +46 -19
- package/studio/server/introspect/bundle.ts +15 -6
- package/studio/server/introspect/canonical-schema.test.ts +79 -0
- package/studio/server/introspect/canonical-schema.ts +80 -18
- package/studio/server/introspect/config-preview.test.ts +32 -0
- package/studio/server/introspect/config-preview.ts +119 -0
- package/studio/server/introspect/diff.test.ts +7 -11
- package/studio/server/introspect/diff.ts +28 -37
- package/studio/server/introspect/extractor.ts +8 -6
- package/studio/server/introspect/hash.ts +5 -2
- package/studio/server/introspect/overlay-tsmorph.ts +7 -1305
- package/studio/server/introspect/revision.test.ts +54 -0
- package/studio/server/introspect/revision.ts +49 -0
- package/studio/server/introspect/runtime.test.ts +63 -5
- package/studio/server/introspect/runtime.ts +49 -3
- package/studio/server/introspect/schema-ir-json.ts +181 -0
- package/studio/server/introspect/source-overlay/annotations.ts +14 -0
- package/studio/server/introspect/source-overlay/handlers.ts +681 -0
- package/studio/server/introspect/source-overlay/kernel-calls.ts +49 -0
- package/studio/server/introspect/source-overlay/project.ts +248 -0
- package/studio/server/introspect/source-overlay/spans.ts +360 -0
- package/studio/server/json.ts +46 -0
- package/studio/server/lifecycle.ts +5 -1
- package/studio/server/sse.test.ts +26 -0
- package/studio/server/sse.ts +4 -1
- package/studio/server/state/baseline.test.ts +212 -1
- package/studio/server/state/baseline.ts +145 -29
- package/studio/server/state/comments.test.ts +66 -1
- package/studio/server/state/comments.ts +173 -10
- package/studio/server/state/context.ts +34 -2
- package/studio/server/state/documents.ts +42 -1
- package/studio/server/state/integrations.ts +27 -1
- package/studio/server/state/layout.test.ts +34 -0
- package/studio/server/state/layout.ts +44 -17
- package/studio/server/state/settings.ts +29 -22
- package/studio/server/state/store.test.ts +122 -0
- package/studio/server/state/store.ts +66 -17
- package/studio/server/state/visibility.ts +22 -7
- package/studio/server/views/model.test.ts +57 -0
- package/studio/server/views/model.ts +66 -0
- package/studio/server/views/runtime.ts +40 -0
- package/studio/server/views/selection-repository.test.ts +31 -0
- package/studio/server/views/selection-repository.ts +60 -0
- package/studio/server/views/session.test.ts +73 -0
- package/studio/server/views/session.ts +166 -0
- package/studio/server/{state/views.test.ts → views/target.test.ts} +8 -159
- package/studio/server/views/target.ts +248 -0
- package/studio/server/watch.ts +1 -1
- package/studio/server/workspace/catalog.test.ts +17 -0
- package/studio/server/workspace/catalog.ts +43 -0
- package/studio/server/{state → workspace}/create.test.ts +1 -1
- package/studio/server/{state → workspace}/create.ts +1 -1
- package/studio/server/{state → workspace}/git.ts +1 -1
- package/studio/server/workspace/updates.ts +83 -0
- package/studio/server/workspace-state.ts +1 -1
- package/studio/shared/contracts/README.md +16 -0
- package/studio/shared/contracts/agent.ts +270 -0
- package/studio/shared/contracts/runtime.ts +50 -0
- package/studio/shared/contracts/schema.ts +462 -0
- package/studio/shared/contracts/surface.test.ts +319 -0
- package/studio/shared/contracts/workspace.ts +274 -0
- package/studio/shared/layout.test.ts +116 -0
- package/studio/shared/schema/identity.test.ts +58 -0
- package/studio/shared/schema/identity.ts +82 -0
- package/studio/shared/types.ts +11 -1099
- package/studio/tsconfig.json +1 -1
- package/viewer/dist/main.js +35 -35
- package/studio/client/dist/assets/index-BMdnsIJA.css +0 -1
- package/studio/client/dist/assets/index-D-vRV8w7.js +0 -8
- package/studio/client/dist/assets/index-LGSWRrk8.js +0 -81
- package/studio/server/state/catalog.ts +0 -117
- package/studio/server/state/instance.ts +0 -280
- package/studio/server/state/updates.ts +0 -63
- package/studio/server/state/views.ts +0 -535
|
@@ -11,7 +11,7 @@ afterEach(() => {
|
|
|
11
11
|
while (roots.length) rmSync(roots.pop()!, { recursive: true, force: true })
|
|
12
12
|
})
|
|
13
13
|
|
|
14
|
-
test('annotates the schema definition behind a current barrel', () => {
|
|
14
|
+
test('workspace creation annotates the schema definition behind a current barrel', () => {
|
|
15
15
|
const root = mkdtempSync(join(tmpdir(), 'studio-create-origin-'))
|
|
16
16
|
roots.push(root)
|
|
17
17
|
mkdirSync(join(root, 'schema', 'application'), { recursive: true })
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Scaffold a brand-new domain into the workspace and bring it
|
|
3
3
|
* online. This is the studio's ONE write that ADDS a domain (every other state
|
|
4
4
|
* module operates on an existing one).
|
|
5
5
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Best-effort workspace Git enrichment for change tracking. The fixtures are not
|
|
3
3
|
* git repos, so EVERY function here degrades gracefully and NEVER throws. The
|
|
4
4
|
* baseline (baseline.ts) is the primary tracker; git only enriches when present.
|
|
5
5
|
*/
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace update bridge for the header Update badge.
|
|
3
|
+
*
|
|
4
|
+
* We don't reimplement staleness: the `astrale` CLI owns it. `astrale update
|
|
5
|
+
* --check --json`, run in the DOMAIN ROOT (so its @astrale-os/* SDK-dep axis sees
|
|
6
|
+
* THIS project), emits a unified `{ stale, cli, sdk }` report. We run it with
|
|
7
|
+
* stdout piped and read it regardless of exit code — a stale result exits 10 by
|
|
8
|
+
* design, which is not an error here. Best-effort: anything unexpected (no
|
|
9
|
+
* bad output) collapses to "nothing stale" so the badge stays
|
|
10
|
+
* hidden rather than nagging on a hiccup.
|
|
11
|
+
*/
|
|
12
|
+
import type { StaleReport } from '../../shared/types'
|
|
13
|
+
|
|
14
|
+
import { decodeJsonObject, runStudioCliJson, runStudioCliText } from '../cli'
|
|
15
|
+
|
|
16
|
+
const NOT_STALE: StaleReport = {
|
|
17
|
+
stale: false,
|
|
18
|
+
cli: { stale: false, managed: true },
|
|
19
|
+
sdk: { stale: false, inProject: false, outdated: [] },
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function getUpdates(root: string): Promise<StaleReport> {
|
|
23
|
+
const result = await runStudioCliJson(['update', '--check', '--json'], decodeStaleReport, {
|
|
24
|
+
cwd: root,
|
|
25
|
+
acceptedExitCodes: [0, 10],
|
|
26
|
+
})
|
|
27
|
+
return result.ok && result.data ? result.data : NOT_STALE
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function decodeStaleReport(value: unknown): StaleReport | null {
|
|
31
|
+
const report = decodeJsonObject(value)
|
|
32
|
+
const cli = decodeJsonObject(report?.cli)
|
|
33
|
+
const sdk = decodeJsonObject(report?.sdk)
|
|
34
|
+
if (
|
|
35
|
+
typeof report?.stale !== 'boolean' ||
|
|
36
|
+
typeof cli?.stale !== 'boolean' ||
|
|
37
|
+
typeof cli.managed !== 'boolean' ||
|
|
38
|
+
typeof sdk?.stale !== 'boolean' ||
|
|
39
|
+
typeof sdk.inProject !== 'boolean' ||
|
|
40
|
+
!Array.isArray(sdk.outdated)
|
|
41
|
+
) {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
const outdated = sdk.outdated.flatMap((value) => {
|
|
45
|
+
const item = decodeJsonObject(value)
|
|
46
|
+
return typeof item?.pkg === 'string' &&
|
|
47
|
+
typeof item.current === 'string' &&
|
|
48
|
+
typeof item.latest === 'string'
|
|
49
|
+
? [{ pkg: item.pkg, current: item.current, latest: item.latest }]
|
|
50
|
+
: []
|
|
51
|
+
})
|
|
52
|
+
if (outdated.length !== sdk.outdated.length) return null
|
|
53
|
+
return {
|
|
54
|
+
stale: report.stale,
|
|
55
|
+
cli: {
|
|
56
|
+
stale: cli.stale,
|
|
57
|
+
managed: cli.managed,
|
|
58
|
+
...(typeof cli.current === 'string' ? { current: cli.current } : {}),
|
|
59
|
+
...(typeof cli.latest === 'string' ? { latest: cli.latest } : {}),
|
|
60
|
+
...(typeof cli.channel === 'string' ? { channel: cli.channel } : {}),
|
|
61
|
+
},
|
|
62
|
+
sdk: { stale: sdk.stale, inProject: sdk.inProject, outdated },
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface UpdateApplyResult {
|
|
67
|
+
ok: boolean
|
|
68
|
+
output: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Apply the update for the header "Update now" button — `astrale update --yes`,
|
|
73
|
+
* run in the domain root. The CLI does the work non-interactively and resiliently
|
|
74
|
+
* (binary + skills + SDK deps; a binary that can't self-update warns but doesn't
|
|
75
|
+
* block the others), so we just spawn it and capture the combined output to show.
|
|
76
|
+
*/
|
|
77
|
+
export async function applyUpdates(root: string): Promise<UpdateApplyResult> {
|
|
78
|
+
const result = await runStudioCliText(['update', '--yes'], { cwd: root })
|
|
79
|
+
return {
|
|
80
|
+
ok: result.ok,
|
|
81
|
+
output: `${result.stdout}${result.stderr}`.trim() || result.detail,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* workspace-state.ts — process-global workspace context shared by the entrypoint
|
|
3
3
|
* (index.ts), the live watcher (workspace-watch.ts), and the create-domain
|
|
4
|
-
* endpoint (
|
|
4
|
+
* endpoint (workspace/create.ts): the scanned ROOT (where new domains are
|
|
5
5
|
* scaffolded), the schema-dir name, and the `domainId → file-watcher stop` map.
|
|
6
6
|
*
|
|
7
7
|
* It exists so the create endpoint can scaffold into the same root the studio
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Studio shared contract boundaries
|
|
2
|
+
|
|
3
|
+
`../types.ts` is the compatibility facade used by existing server and client
|
|
4
|
+
imports. Definitions live under one semantic owner:
|
|
5
|
+
|
|
6
|
+
- `schema.ts` owns the render IR and all schema/anatomy introspection results.
|
|
7
|
+
- `workspace.ts` owns persisted and workspace-facing state, including the sole
|
|
8
|
+
`LayoutState` and `VisibilityState` definitions.
|
|
9
|
+
- `agent.ts` owns the harness-neutral agent protocol and harness configuration.
|
|
10
|
+
- `runtime.ts` owns Studio runtime configuration, SSE events, and CLI staleness.
|
|
11
|
+
- `../schema/identity.ts` owns pure canonical reference/key identity helpers.
|
|
12
|
+
|
|
13
|
+
Allowed dependency direction is identity → schema → workspace → agent → runtime.
|
|
14
|
+
Shared contracts never import server or client implementations. New consumers
|
|
15
|
+
may import an owning module directly; `@shared/types` remains supported for
|
|
16
|
+
compatibility.
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared agent and harness protocol.
|
|
3
|
+
*
|
|
4
|
+
* These shapes are harness-neutral and describe Studio's recorded conversation,
|
|
5
|
+
* capability, loadout, usage, and gateway configuration surfaces.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { MergeResult } from './workspace'
|
|
9
|
+
|
|
10
|
+
/** Kinds of activity the studio surfaces while a local agent runs a turn. */
|
|
11
|
+
export type AgentEventKind = 'status' | 'thinking' | 'message' | 'tool' | 'reply' | 'error'
|
|
12
|
+
|
|
13
|
+
export interface AgentEvent {
|
|
14
|
+
id: string
|
|
15
|
+
ts: string
|
|
16
|
+
kind: AgentEventKind
|
|
17
|
+
text: string
|
|
18
|
+
/** for kind:'tool' — the tool name (Edit/Write/Bash/Read…) */
|
|
19
|
+
tool?: string
|
|
20
|
+
/** for kind:'tool' — a compact target (file path, command, pattern) */
|
|
21
|
+
target?: string
|
|
22
|
+
/** for kind:'reply' — the comment id the reply landed on */
|
|
23
|
+
commentId?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const AGENT_EFFORT_LEVELS = [
|
|
27
|
+
'minimal',
|
|
28
|
+
'low',
|
|
29
|
+
'medium',
|
|
30
|
+
'high',
|
|
31
|
+
'xhigh',
|
|
32
|
+
'max',
|
|
33
|
+
'ultracode',
|
|
34
|
+
] as const
|
|
35
|
+
export type AgentEffort = (typeof AGENT_EFFORT_LEVELS)[number]
|
|
36
|
+
export const AGENT_ACCESS_LEVELS = ['workspace', 'full'] as const
|
|
37
|
+
export type AgentAccess = (typeof AGENT_ACCESS_LEVELS)[number]
|
|
38
|
+
|
|
39
|
+
export interface AgentPromptSnapshot {
|
|
40
|
+
createdAt: string
|
|
41
|
+
/** appended to the harness default system prompt */
|
|
42
|
+
systemPrompt: string
|
|
43
|
+
/** piped to the harness on stdin */
|
|
44
|
+
turnPrompt: string
|
|
45
|
+
/** true when this turn started a new harness conversation */
|
|
46
|
+
firstTurn: boolean
|
|
47
|
+
/** true when this turn used a prior harness session id */
|
|
48
|
+
resumed: boolean
|
|
49
|
+
sessionId?: string
|
|
50
|
+
/** Explicit Studio model override used for this turn; absent means harness-native default. */
|
|
51
|
+
model?: string
|
|
52
|
+
/** Harness-native reasoning effort used for this turn. */
|
|
53
|
+
effort?: AgentEffort
|
|
54
|
+
/** Filesystem/network authority granted to the harness for this turn. */
|
|
55
|
+
access?: AgentAccess
|
|
56
|
+
/** generated MCP bridge tools exposed to the harness for live write-back */
|
|
57
|
+
mcpTools: string[]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface AgentSystemPromptInfo {
|
|
61
|
+
bridge: boolean
|
|
62
|
+
systemPrompt: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type AgentRunStatus =
|
|
66
|
+
| 'queued'
|
|
67
|
+
| 'running'
|
|
68
|
+
| 'succeeded'
|
|
69
|
+
| 'failed'
|
|
70
|
+
| 'canceled'
|
|
71
|
+
/** the studio process died mid-turn (restart/crash) — the spawned agent went with
|
|
72
|
+
* it, but the CONVERSATION is preserved, so the next submit resumes it. */
|
|
73
|
+
| 'interrupted'
|
|
74
|
+
|
|
75
|
+
/** One agent turn for a domain: the live transcript + outcome. */
|
|
76
|
+
export interface AgentRun {
|
|
77
|
+
id: string
|
|
78
|
+
domainId: string
|
|
79
|
+
harness: string
|
|
80
|
+
status: AgentRunStatus
|
|
81
|
+
createdAt: string
|
|
82
|
+
finishedAt?: string
|
|
83
|
+
/** the harness session id (so the next turn resumes the same conversation) */
|
|
84
|
+
sessionId?: string
|
|
85
|
+
/** true ⇒ this turn resumed an existing conversation (vs. started a new one) */
|
|
86
|
+
resumed?: boolean
|
|
87
|
+
/** short human label of what this turn was asked to do */
|
|
88
|
+
summary: string
|
|
89
|
+
/** comment ids this turn was started to answer */
|
|
90
|
+
targetCommentIds: string[]
|
|
91
|
+
events: AgentEvent[]
|
|
92
|
+
costUsd?: number
|
|
93
|
+
numTurns?: number
|
|
94
|
+
/** total token usage reported by the harness for this turn */
|
|
95
|
+
tokens?: number
|
|
96
|
+
error?: string
|
|
97
|
+
/** how many threads the agent answered live via the bridge tools this turn */
|
|
98
|
+
liveReplies?: number
|
|
99
|
+
/** result of merging the agent's final machine-state reply block, if any */
|
|
100
|
+
merge?: MergeResult
|
|
101
|
+
/** exact prompt inputs sent to the harness for this turn */
|
|
102
|
+
prompt?: AgentPromptSnapshot
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The ongoing, resumable conversation for a domain and selected harness.
|
|
106
|
+
* Survives studio restarts (persisted on disk). */
|
|
107
|
+
export interface ConversationInfo {
|
|
108
|
+
/** a resumable session exists → the next submit continues it (vs. starting fresh) */
|
|
109
|
+
active: boolean
|
|
110
|
+
/** successful turns recorded in the current conversation */
|
|
111
|
+
turns: number
|
|
112
|
+
/** which harness the conversation belongs to (resume only applies within it) */
|
|
113
|
+
harness?: string
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** The agent's raw resumable session id, surfaced for manual view/edit in Settings. */
|
|
117
|
+
export interface AgentSessionInfo {
|
|
118
|
+
sessionId: string | null
|
|
119
|
+
turns: number
|
|
120
|
+
harness?: string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface HarnessCapabilities {
|
|
124
|
+
effortLevels: readonly AgentEffort[]
|
|
125
|
+
accessLevels: readonly AgentAccess[]
|
|
126
|
+
/** Stable aliases advertised even when the harness has no catalog API. */
|
|
127
|
+
modelOptions?: readonly HarnessModelOption[]
|
|
128
|
+
ask: boolean
|
|
129
|
+
loadout: boolean
|
|
130
|
+
/** Custom model-gateway wire contract this harness can consume in Studio. */
|
|
131
|
+
gateway: 'anthropic' | 'responses' | 'none'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Whether the selected agent harness is installed, invokable, and configurable. */
|
|
135
|
+
export interface HarnessStatus {
|
|
136
|
+
id: string
|
|
137
|
+
label: string
|
|
138
|
+
/** the binary/command probed (e.g. 'claude') */
|
|
139
|
+
bin: string
|
|
140
|
+
ok: boolean
|
|
141
|
+
version?: string
|
|
142
|
+
/** human message — install / PATH guidance when not ok */
|
|
143
|
+
message: string
|
|
144
|
+
/** known harnesses for the selector (locked to one for now) */
|
|
145
|
+
options: { id: string; label: string }[]
|
|
146
|
+
/** an environment/CLI override owns the selection, so the GUI cannot change it */
|
|
147
|
+
locked: boolean
|
|
148
|
+
source: 'environment' | 'domain' | 'default'
|
|
149
|
+
capabilities: HarnessCapabilities
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** One MCP server the harness loaded, with its live connection status. */
|
|
153
|
+
export interface McpServerInfo {
|
|
154
|
+
name: string
|
|
155
|
+
/** harness-reported status: 'connected' | 'needs-auth' | 'failed' | 'pending' | … */
|
|
156
|
+
status: string
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** One skill, reconciled between what is installed on disk and what the harness
|
|
160
|
+
* actually LOADED for this domain's cwd. */
|
|
161
|
+
export interface LoadoutSkill {
|
|
162
|
+
/** the slash-command the harness invokes it by — e.g. 'astrale-domain' or 'vercel:nextjs' */
|
|
163
|
+
command: string
|
|
164
|
+
/** display name from SKILL.md frontmatter (falls back to `command`) */
|
|
165
|
+
name: string
|
|
166
|
+
description?: string
|
|
167
|
+
/** where it lives on disk */
|
|
168
|
+
source: 'project' | 'user' | 'plugin'
|
|
169
|
+
/** the providing plugin, when source==='plugin' */
|
|
170
|
+
plugin?: string
|
|
171
|
+
/** present in the harness's loaded slash-commands for this cwd */
|
|
172
|
+
loaded: boolean
|
|
173
|
+
/** absolute path to the skill's SKILL.md (so the UI can show its content) */
|
|
174
|
+
path?: string
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** What the harness actually loaded for a domain's cwd. */
|
|
178
|
+
export interface HarnessLoadout {
|
|
179
|
+
/** the probe ran and returned an init event */
|
|
180
|
+
ok: boolean
|
|
181
|
+
/** reason when !ok (binary missing / probe timed out / no init event) */
|
|
182
|
+
detail?: string
|
|
183
|
+
/** Model the harness resolves before Studio applies its optional override. */
|
|
184
|
+
nativeModel?: string
|
|
185
|
+
model?: string
|
|
186
|
+
/** Where the effective model came from. */
|
|
187
|
+
modelSource?: 'studio' | 'config' | 'default' | 'runtime'
|
|
188
|
+
/** Models the harness currently advertises for easy selection. */
|
|
189
|
+
models?: HarnessModelOption[]
|
|
190
|
+
permissionMode?: string
|
|
191
|
+
/** how the harness is authed: 'none' | 'ANTHROPIC_API_KEY' | … */
|
|
192
|
+
apiKeySource?: string
|
|
193
|
+
/** the cwd the harness was probed in (the domain root) */
|
|
194
|
+
cwd?: string
|
|
195
|
+
/** built-in tool names loaded (Read, Edit, Bash, …) */
|
|
196
|
+
tools: string[]
|
|
197
|
+
mcpServers: McpServerInfo[]
|
|
198
|
+
skills: LoadoutSkill[]
|
|
199
|
+
/** subagent types available to the harness (incl. plugin-provided) */
|
|
200
|
+
agents: string[]
|
|
201
|
+
/** count of loaded slash-commands that are built-in/harness commands, not skills */
|
|
202
|
+
builtinCommandCount: number
|
|
203
|
+
/** epoch ms when probed */
|
|
204
|
+
probedAt: number
|
|
205
|
+
/** Claude exposes a live init event; Codex exposes configured/installed state. */
|
|
206
|
+
source?: 'runtime' | 'configured'
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface HarnessModelOption {
|
|
210
|
+
/** Stable model slug passed to the harness, e.g. `gpt-5.6-sol`. */
|
|
211
|
+
id: string
|
|
212
|
+
/** Human-friendly catalog label. */
|
|
213
|
+
label: string
|
|
214
|
+
description?: string
|
|
215
|
+
/** The harness catalog's built-in default when no config layer overrides it. */
|
|
216
|
+
isDefault?: boolean
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Domain-attributable agent spend — accumulated from this studio's own runs on
|
|
220
|
+
* this domain (NOT machine-wide). Stored at `.domain-studio/usage.json`. */
|
|
221
|
+
export interface DomainUsage {
|
|
222
|
+
/** runs that reported usage (succeeded or not — a failed turn still costs) */
|
|
223
|
+
runs: number
|
|
224
|
+
/** cumulative tokens (input + output + cache) across those runs */
|
|
225
|
+
tokens: number
|
|
226
|
+
/** cumulative USD across those runs */
|
|
227
|
+
costUsd: number
|
|
228
|
+
lastRunAt?: string
|
|
229
|
+
lastTokens?: number
|
|
230
|
+
lastCostUsd?: number
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** Snapshot returned by GET /agent — drives the activity drawer. */
|
|
234
|
+
export interface AgentRunSnapshot {
|
|
235
|
+
harness: string
|
|
236
|
+
available: boolean
|
|
237
|
+
/** the active or most-recent run for this domain (null if none yet) */
|
|
238
|
+
run: AgentRun | null
|
|
239
|
+
/** the resumable conversation behind the runs (turns, whether one is live) */
|
|
240
|
+
conversation: ConversationInfo
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** How the harness gets its bearer token for a custom model gateway. */
|
|
244
|
+
export type HarnessGatewayAuth =
|
|
245
|
+
| { mode: 'mint'; instance?: string }
|
|
246
|
+
| { mode: 'token'; token: string }
|
|
247
|
+
| { mode: 'host' }
|
|
248
|
+
|
|
249
|
+
export interface HarnessGatewayConfig {
|
|
250
|
+
/** master switch — off ⇒ the harness uses its own default auth */
|
|
251
|
+
enabled: boolean
|
|
252
|
+
/** ANTHROPIC_BASE_URL used by the spawned harness child only. */
|
|
253
|
+
baseUrl: string
|
|
254
|
+
/** ANTHROPIC_MODEL label; the gateway may pin the real model by URL. */
|
|
255
|
+
model?: string
|
|
256
|
+
/** how the bearer token is obtained */
|
|
257
|
+
auth: HarnessGatewayAuth
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/** The layered harness-gateway config for a domain. */
|
|
261
|
+
export interface HarnessGatewayState {
|
|
262
|
+
/** per-domain override (`.domain-studio/harness-gateway.json`); null ⇒ inherits global */
|
|
263
|
+
local: HarnessGatewayConfig | null
|
|
264
|
+
/** studio-wide default — applies to every domain that has no local override */
|
|
265
|
+
global: HarnessGatewayConfig | null
|
|
266
|
+
/** the config that actually takes effect, else null */
|
|
267
|
+
effective: HarnessGatewayConfig | null
|
|
268
|
+
/** which layer `effective` came from */
|
|
269
|
+
source: 'domain' | 'global' | 'none'
|
|
270
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Studio runtime and API transport contracts.
|
|
3
|
+
*
|
|
4
|
+
* This owner contains cross-process notifications, Studio runtime settings, and
|
|
5
|
+
* CLI-owned update reports. It does not define schema or persisted workspace state.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { AgentAccess, AgentEffort, AgentEvent, AgentRun } from './agent'
|
|
9
|
+
|
|
10
|
+
export type StudioEvent =
|
|
11
|
+
| { type: 'schema-diff'; domainId: string; renderFingerprint: string }
|
|
12
|
+
| { type: 'anatomy-diff'; domainId: string }
|
|
13
|
+
| { type: 'comments'; domainId: string }
|
|
14
|
+
| { type: 'compile-error'; domainId: string; message: string }
|
|
15
|
+
| { type: 'resolving'; domainId: string }
|
|
16
|
+
| { type: 'agent-run'; domainId: string; run: AgentRun }
|
|
17
|
+
| { type: 'agent-event'; domainId: string; runId: string; event: AgentEvent }
|
|
18
|
+
| { type: 'hello'; domains: string[] }
|
|
19
|
+
| { type: 'workspace'; domains: string[] }
|
|
20
|
+
|
|
21
|
+
/** Per-domain overrides stored at `.domain-studio/settings.json`. */
|
|
22
|
+
export interface StudioSettings {
|
|
23
|
+
/** Harness-native reasoning effort (default 'high') */
|
|
24
|
+
agentEffort: AgentEffort
|
|
25
|
+
/** workspace = sandboxed edits; full = unrestricted local automation */
|
|
26
|
+
agentAccess: AgentAccess
|
|
27
|
+
/** Optional model override, independently remembered for each harness id. */
|
|
28
|
+
agentModels: Record<string, string>
|
|
29
|
+
/** folder under the domain root scanned for integrations (default 'integrations') */
|
|
30
|
+
integrationsDir: string
|
|
31
|
+
/** schema/core extraction subprocess timeout in ms (default 20000) */
|
|
32
|
+
introspectTimeoutMs: number
|
|
33
|
+
/** how often the per-domain instance status refreshes, ms (default 30000) */
|
|
34
|
+
instancePollMs: number
|
|
35
|
+
/** how often the studio re-checks for stale schema / updates, ms (default 600000) */
|
|
36
|
+
updatesPollMs: number
|
|
37
|
+
/** timeout when probing a live view URL from the instance, ms (default 8000) */
|
|
38
|
+
viewProbeTimeoutMs: number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The Astrale CLI's `astrale update --check --json` report. */
|
|
42
|
+
export interface StaleReport {
|
|
43
|
+
stale: boolean
|
|
44
|
+
cli: { stale: boolean; managed: boolean; current?: string; latest?: string; channel?: string }
|
|
45
|
+
sdk: {
|
|
46
|
+
stale: boolean
|
|
47
|
+
inProject: boolean
|
|
48
|
+
outdated: { pkg: string; current: string; latest: string }[]
|
|
49
|
+
}
|
|
50
|
+
}
|