acryl-cli-linux-x64 0.1.35 → 0.1.36
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/package.json +1 -1
- package/runtime/lib/bin.js +218 -206
- package/runtime/lib/index.js +220 -206
- package/runtime/lib/types/tui/actions.d.ts +2 -1
- package/runtime/lib/types/tui/listWindow.d.ts +24 -0
- package/runtime/lib/types/tui/login/LoginOverlay.d.ts +19 -13
- package/runtime/lib/types/tui/login/types.d.ts +2 -1
- package/runtime/lib/types/tui/modelProfile/ModelProfileOverlay.d.ts +0 -14
- package/runtime/lib/types/tui/modelProfile/types.d.ts +3 -2
- package/runtime/lib/types/yly/yly-pet.d.ts +1 -1
- package/runtime/lib/types/yly/yly-programs.d.ts +1 -1
- package/runtime/node_modules/.modules.yaml +1 -1
- package/runtime/node_modules/.package-map.json +1 -1
- package/runtime/node_modules/acryl-control/lib/index.js +66 -1
- package/runtime/node_modules/acryl-control/lib/types/authorization/service.d.ts +23 -0
- package/runtime/node_modules/acryl-control/lib/types/authorization/types.d.ts +46 -0
- package/runtime/node_modules/acryl-control/lib/types/credential/projection.d.ts +63 -0
- package/runtime/node_modules/acryl-control/lib/types/credential/types.d.ts +38 -0
- package/runtime/node_modules/acryl-control/lib/types/index.d.ts +4 -0
- package/runtime/node_modules/acryl-control/package.json +1 -1
- package/runtime/node_modules/acryl-harness-runtime/package.json +1 -1
- package/runtime/package.json +2 -2
- package/runtime/receipt.json +2 -2
|
@@ -348,6 +348,71 @@ function parseAcrylSessionSnapshot(value) {
|
|
|
348
348
|
});
|
|
349
349
|
}
|
|
350
350
|
//#endregion
|
|
351
|
+
//#region src/credential/projection.ts
|
|
352
|
+
/** Read a nested value out of an untyped resolved/raw settings section. */
|
|
353
|
+
function getAtPath(value, path) {
|
|
354
|
+
let current = value;
|
|
355
|
+
for (const key of path) {
|
|
356
|
+
if (current === null || typeof current !== "object") return void 0;
|
|
357
|
+
current = current[key];
|
|
358
|
+
}
|
|
359
|
+
return current;
|
|
360
|
+
}
|
|
361
|
+
/** Compute every provider route's joined credential/settings/live-registration row. */
|
|
362
|
+
async function computeCredentialProjection(services, options) {
|
|
363
|
+
const scope = options.loginRecordScope ?? "llm-pi-ai";
|
|
364
|
+
const configurable = services.llm.listConfigurableProviders();
|
|
365
|
+
const live = new Set(services.llm.listProviders().map((provider) => provider.id));
|
|
366
|
+
const descriptors = services.settings.describe({ redactSecrets: true });
|
|
367
|
+
const byNs = new Map(descriptors.map((descriptor) => [descriptor.ns, descriptor]));
|
|
368
|
+
const rows = [];
|
|
369
|
+
for (const entry of configurable) {
|
|
370
|
+
const descriptor = byNs.get(entry.settingsNs);
|
|
371
|
+
const value = descriptor === void 0 ? void 0 : getAtPath(descriptor.value, entry.settingsPath);
|
|
372
|
+
const userValue = descriptor === void 0 ? void 0 : getAtPath(descriptor.user, entry.settingsPath);
|
|
373
|
+
const apiKeyRef = value?.apiKeyEnv ?? options.deriveApiKeyRef(entry.provider);
|
|
374
|
+
const info = await services.credentials.describe(apiKeyRef);
|
|
375
|
+
const loginRecord = await services.credentials.readRecord?.(`${scope}/${entry.provider}`);
|
|
376
|
+
const authMethod = loginRecord !== void 0 ? loginRecord.kind === "grant" ? "oauth" : "api-key" : info.configured ? "api-key" : void 0;
|
|
377
|
+
const isLive = live.has(entry.provider);
|
|
378
|
+
const models = isLive ? await services.llm.listModels(entry.provider).catch(() => value?.models ?? []) : value?.models ?? [];
|
|
379
|
+
rows.push({
|
|
380
|
+
route: entry.provider,
|
|
381
|
+
displayName: value?.displayName ?? entry.displayName,
|
|
382
|
+
settingsNs: entry.settingsNs,
|
|
383
|
+
settingsPath: entry.settingsPath,
|
|
384
|
+
hasSettingsProfile: userValue !== void 0,
|
|
385
|
+
hasCredential: info.configured || loginRecord !== void 0,
|
|
386
|
+
isLive,
|
|
387
|
+
authMethod,
|
|
388
|
+
api: value?.api,
|
|
389
|
+
baseURL: value?.baseURL,
|
|
390
|
+
apiKeyRef,
|
|
391
|
+
models,
|
|
392
|
+
revision: descriptor?.revision
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
return rows;
|
|
396
|
+
}
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/authorization/service.ts
|
|
399
|
+
var AuthorizationService = class {
|
|
400
|
+
deps;
|
|
401
|
+
constructor(deps) {
|
|
402
|
+
this.deps = deps;
|
|
403
|
+
}
|
|
404
|
+
async begin(request) {
|
|
405
|
+
const outcome = await this.deps.authorization.begin(request);
|
|
406
|
+
if (outcome.status === "authorized") {
|
|
407
|
+
const slash = request.key.indexOf("/");
|
|
408
|
+
const providerId = slash === -1 ? request.key : request.key.slice(slash + 1);
|
|
409
|
+
if (this.deps.routeActivation !== void 0) await this.deps.routeActivation.ensureRouteActivated(providerId, request.method);
|
|
410
|
+
this.deps.onCredentialChanged(request.key);
|
|
411
|
+
}
|
|
412
|
+
return outcome;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
//#endregion
|
|
351
416
|
//#region src/lifecycle/controller.ts
|
|
352
417
|
var PluginLifecycleError = class extends Error {
|
|
353
418
|
code;
|
|
@@ -530,6 +595,6 @@ function nonEmptyCommandId(value) {
|
|
|
530
595
|
return value;
|
|
531
596
|
}
|
|
532
597
|
//#endregion
|
|
533
|
-
export { AcrAgentControlError, AcrAgentControlService, AcrPluginLifecycleController, AcrPluginLifecycleService, AcrRuntimeArchitectureService, Context, PROVIDER_CAPABILITIES, PluginLifecycleError, Service, acpProvider, claudeProvider, codexProvider, createAcrylSessionClient, createProviderPlugin, dshNativeProvider, parseAcrylSessionSnapshot, projectRuntimeArchitecture };
|
|
598
|
+
export { AcrAgentControlError, AcrAgentControlService, AcrPluginLifecycleController, AcrPluginLifecycleService, AcrRuntimeArchitectureService, AuthorizationService, Context, PROVIDER_CAPABILITIES, PluginLifecycleError, Service, acpProvider, claudeProvider, codexProvider, computeCredentialProjection, createAcrylSessionClient, createProviderPlugin, dshNativeProvider, parseAcrylSessionSnapshot, projectRuntimeArchitecture };
|
|
534
599
|
|
|
535
600
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `AuthorizationService`: the `beginAuthorization` use-case, owned outside
|
|
3
|
+
* the terminal surface (finding R1). Forwards to the underlying
|
|
4
|
+
* `AuthorizationPort`, activates the route on success (no display-name
|
|
5
|
+
* encoding — the `-oauth` suffix hack is deleted, not moved; see finding R2),
|
|
6
|
+
* and emits `credential.changed` so subscribers can invalidate a targeted
|
|
7
|
+
* projection instead of a shotgun dual reload (finding R4).
|
|
8
|
+
*
|
|
9
|
+
* Framework-free: every dependency is a plain port, so this is directly
|
|
10
|
+
* unit-testable with stubs — no Cordis boot required.
|
|
11
|
+
*/
|
|
12
|
+
import type { AuthorizationBeginRequest, AuthorizationOutcome, AuthorizationPort, CredentialChangedListener, RouteActivationPort } from './types.ts';
|
|
13
|
+
export interface AuthorizationServiceDeps {
|
|
14
|
+
readonly authorization: AuthorizationPort;
|
|
15
|
+
/** Optional: absent profiles degrade to "not available" (matches the surface's own optional-service pattern). */
|
|
16
|
+
readonly routeActivation?: RouteActivationPort;
|
|
17
|
+
readonly onCredentialChanged: CredentialChangedListener;
|
|
18
|
+
}
|
|
19
|
+
export declare class AuthorizationService {
|
|
20
|
+
private readonly deps;
|
|
21
|
+
constructor(deps: AuthorizationServiceDeps);
|
|
22
|
+
begin(request: AuthorizationBeginRequest): Promise<AuthorizationOutcome>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Typed authorization use-case contract: `/login`'s `beginAuthorization` action. */
|
|
2
|
+
/** A question the running flow needs answered before it can continue (opaque pass-through). */
|
|
3
|
+
export interface AuthorizationInteraction {
|
|
4
|
+
notify(notice: {
|
|
5
|
+
readonly message: string;
|
|
6
|
+
readonly url?: string;
|
|
7
|
+
readonly code?: string;
|
|
8
|
+
}): void;
|
|
9
|
+
prompt(prompt: {
|
|
10
|
+
readonly kind: 'text' | 'secret' | 'select';
|
|
11
|
+
readonly message: string;
|
|
12
|
+
readonly options?: readonly {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly label: string;
|
|
15
|
+
readonly description?: string;
|
|
16
|
+
}[];
|
|
17
|
+
readonly placeholder?: string;
|
|
18
|
+
readonly signal?: AbortSignal;
|
|
19
|
+
}): Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
export interface AuthorizationBeginRequest {
|
|
22
|
+
/** The credential record key this flow writes (`<scope>/<id>`). */
|
|
23
|
+
readonly key: string;
|
|
24
|
+
readonly method: string | undefined;
|
|
25
|
+
readonly interaction: AuthorizationInteraction;
|
|
26
|
+
}
|
|
27
|
+
export interface AuthorizationOutcome {
|
|
28
|
+
readonly status: string;
|
|
29
|
+
readonly [extra: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
/** The underlying pi-ai (or equivalent) authorization flow runner. */
|
|
32
|
+
export interface AuthorizationPort {
|
|
33
|
+
begin(request: AuthorizationBeginRequest): Promise<AuthorizationOutcome>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Make a route usable from `/model` after a successful sign-in: `dsh-llm-pi-ai`
|
|
37
|
+
* only registers a route as live once its settings section names it (even an
|
|
38
|
+
* empty profile — "use the installed catalog's defaults" — counts), so a
|
|
39
|
+
* signed-in-but-never-configured route stays credentialed but absent from
|
|
40
|
+
* `ctx.llm`'s live directory otherwise. A no-op when the route already has a
|
|
41
|
+
* settings profile, so it never clobbers one the user already configured.
|
|
42
|
+
*/
|
|
43
|
+
export interface RouteActivationPort {
|
|
44
|
+
ensureRouteActivated(providerId: string, method: string | undefined): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
export type CredentialChangedListener = (key: string) => void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `CredentialProjection`: the one join of `ctx.llm` + `ctx.settings` +
|
|
3
|
+
* `ctx.credentials` into provider rows. Replaces the surface's own
|
|
4
|
+
* `computeProviderRows`/`loadAuthorizationFlows` duplicate joins (finding R1)
|
|
5
|
+
* so `/login` and `/model` read the same projection instead of two
|
|
6
|
+
* independently-fetched pictures of the same state.
|
|
7
|
+
*
|
|
8
|
+
* Framework-free: takes plain service ports (not a Cordis `Context`), so it
|
|
9
|
+
* is directly unit-testable with stubs — no Cordis boot required. The
|
|
10
|
+
* surface wires these ports from `host.ctx.get(...)`.
|
|
11
|
+
*/
|
|
12
|
+
import type { CredentialModelEntry, CredentialProjectionRow } from './types.ts';
|
|
13
|
+
export interface CredentialProjectionConfigurableProvider {
|
|
14
|
+
readonly provider: string;
|
|
15
|
+
readonly displayName: string;
|
|
16
|
+
readonly settingsNs: string;
|
|
17
|
+
readonly settingsPath: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
export interface CredentialProjectionLlmPort {
|
|
20
|
+
listConfigurableProviders(): readonly CredentialProjectionConfigurableProvider[];
|
|
21
|
+
listProviders(): readonly {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
}[];
|
|
24
|
+
listModels(provider: string): Promise<readonly CredentialModelEntry[]>;
|
|
25
|
+
}
|
|
26
|
+
export interface CredentialProjectionSettingsDescriptor {
|
|
27
|
+
readonly ns: string;
|
|
28
|
+
readonly value: unknown;
|
|
29
|
+
readonly user?: unknown;
|
|
30
|
+
readonly revision?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface CredentialProjectionSettingsPort {
|
|
33
|
+
describe(options: {
|
|
34
|
+
readonly redactSecrets: boolean;
|
|
35
|
+
}): readonly CredentialProjectionSettingsDescriptor[];
|
|
36
|
+
}
|
|
37
|
+
export interface CredentialProjectionRecord {
|
|
38
|
+
readonly kind: string;
|
|
39
|
+
}
|
|
40
|
+
export interface CredentialProjectionCredentialsPort {
|
|
41
|
+
describe(ref: string): Promise<{
|
|
42
|
+
readonly configured: boolean;
|
|
43
|
+
}>;
|
|
44
|
+
readRecord?(key: string): Promise<CredentialProjectionRecord | undefined>;
|
|
45
|
+
}
|
|
46
|
+
export interface CredentialProjectionServices {
|
|
47
|
+
readonly llm: CredentialProjectionLlmPort;
|
|
48
|
+
readonly settings: CredentialProjectionSettingsPort;
|
|
49
|
+
readonly credentials: CredentialProjectionCredentialsPort;
|
|
50
|
+
}
|
|
51
|
+
export interface CredentialProjectionOptions {
|
|
52
|
+
/** Derive the settings-fallback `apiKeyEnv` reference for a route with no stored profile. */
|
|
53
|
+
readonly deriveApiKeyRef: (route: string) => string;
|
|
54
|
+
/**
|
|
55
|
+
* The scope a `/login` sign-in's own credential record lives under
|
|
56
|
+
* (`dsh-llm-pi-ai`'s `credentialKey(scope, providerId)`), separate from the
|
|
57
|
+
* `apiKeyEnv` reference a manually configured provider's settings profile
|
|
58
|
+
* points at. Defaults to `'llm-pi-ai'`.
|
|
59
|
+
*/
|
|
60
|
+
readonly loginRecordScope?: string;
|
|
61
|
+
}
|
|
62
|
+
/** Compute every provider route's joined credential/settings/live-registration row. */
|
|
63
|
+
export declare function computeCredentialProjection(services: CredentialProjectionServices, options: CredentialProjectionOptions): Promise<readonly CredentialProjectionRow[]>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed read-model for a provider route's credential/authorization state.
|
|
3
|
+
* `/login` and `/model` (in `acryl-cli`) both consume the *same* projection —
|
|
4
|
+
* this is the one place `hasCredential`/`hasSettingsProfile`/`isLive`/
|
|
5
|
+
* `authMethod` are defined, so no field means two different things across
|
|
6
|
+
* the two overlays (see `specs/001-acryl-refactor-improvements-and-tech-debt`,
|
|
7
|
+
* finding R3).
|
|
8
|
+
*/
|
|
9
|
+
/** How a stored credential was obtained. */
|
|
10
|
+
export type AuthMethod = 'oauth' | 'api-key';
|
|
11
|
+
/** One model entry within a provider's catalog (subset shared with the surface's own `ModelEntry`). */
|
|
12
|
+
export interface CredentialModelEntry {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly name?: string;
|
|
15
|
+
readonly contextWindow?: number;
|
|
16
|
+
readonly maxTokens?: number;
|
|
17
|
+
}
|
|
18
|
+
/** One provider route, joined from `ctx.llm` + `ctx.settings` + `ctx.credentials`. */
|
|
19
|
+
export interface CredentialProjectionRow {
|
|
20
|
+
readonly route: string;
|
|
21
|
+
readonly displayName: string;
|
|
22
|
+
readonly settingsNs: string;
|
|
23
|
+
readonly settingsPath: readonly string[];
|
|
24
|
+
/** Whether the user's settings document has an override for this route (a `/model` save, not a `/login` sign-in). */
|
|
25
|
+
readonly hasSettingsProfile: boolean;
|
|
26
|
+
/** Whether a credential — an `apiKeyEnv` secret or a `/login` record — is stored for this route. */
|
|
27
|
+
readonly hasCredential: boolean;
|
|
28
|
+
/** Whether the route is currently registered/live in `ctx.llm`. */
|
|
29
|
+
readonly isLive: boolean;
|
|
30
|
+
/** How the credential behind `hasCredential` was obtained, or `undefined` when none is configured. */
|
|
31
|
+
readonly authMethod: AuthMethod | undefined;
|
|
32
|
+
readonly api: string | undefined;
|
|
33
|
+
readonly baseURL: string | undefined;
|
|
34
|
+
readonly apiKeyRef: string;
|
|
35
|
+
readonly models: readonly CredentialModelEntry[];
|
|
36
|
+
/** Settings revision this row was read at; replay as `expectedRevision` on write. */
|
|
37
|
+
readonly revision: number | undefined;
|
|
38
|
+
}
|
|
@@ -10,6 +10,10 @@ export * from './architecture/projection.ts';
|
|
|
10
10
|
export * from './architecture/provider.ts';
|
|
11
11
|
export * from './contracts/operations.ts';
|
|
12
12
|
export * from './contracts/session.ts';
|
|
13
|
+
export * from './credential/types.ts';
|
|
14
|
+
export * from './credential/projection.ts';
|
|
15
|
+
export * from './authorization/types.ts';
|
|
16
|
+
export * from './authorization/service.ts';
|
|
13
17
|
export * from './events.ts';
|
|
14
18
|
export * from './lifecycle/controller.ts';
|
|
15
19
|
export * from './lifecycle/provider.ts';
|
package/runtime/package.json
CHANGED
package/runtime/receipt.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"surface": "cli",
|
|
4
4
|
"target": "linux-x64",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.36",
|
|
6
6
|
"packageName": "acryl-cli-linux-x64",
|
|
7
|
-
"payloadSha256": "
|
|
7
|
+
"payloadSha256": "99de89fd03be2f9ae485b5d15b52063a909928eaff7c9330f178d98e55a22a32"
|
|
8
8
|
}
|