@undefineds.co/linx 0.3.16 → 0.3.17
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/dist/generated/version.js +1 -1
- package/dist/lib/auto-mode/secretary.js +2 -2
- package/dist/lib/auto-mode/secretary.js.map +1 -1
- package/dist/lib/models.js +2 -3
- package/dist/lib/models.js.map +1 -1
- package/dist/lib/pi-adapter/session.js +17 -13
- package/dist/lib/pi-adapter/session.js.map +1 -1
- package/dist/lib/symphony/pod-projection.js +526 -12
- package/dist/lib/symphony/pod-projection.js.map +1 -1
- package/dist/skills/symphony/SKILL.md +50 -0
- package/package.json +2 -2
- package/vendor/agent-runtime/dist/index.d.ts +0 -2
- package/vendor/agent-runtime/dist/index.js +0 -2
- package/vendor/agent-runtime/dist/reconciler.js +2 -2
- package/vendor/agent-runtime/dist/symphony.js +6 -5
- package/vendor/agent-runtime/package.json +1 -3
- package/dist/lib/pi-adapter/auth.js +0 -68
- package/dist/lib/pi-adapter/auth.js.map +0 -1
- package/dist/lib/pi-adapter/pod-tools.js +0 -140
- package/dist/lib/pi-adapter/pod-tools.js.map +0 -1
- package/dist/lib/resource-identity.js +0 -2
- package/dist/lib/resource-identity.js.map +0 -1
- package/vendor/agent-runtime/dist/pod-resource-identity.d.ts +0 -17
- package/vendor/agent-runtime/dist/pod-resource-identity.js +0 -54
- package/vendor/agent-runtime/dist/workspace.d.ts +0 -33
- package/vendor/agent-runtime/dist/workspace.js +0 -80
|
@@ -245,10 +245,10 @@ export function renderSymphonyRuntimePrompt(input) {
|
|
|
245
245
|
...(input.workspace.environment ? [`Workspace environment: ${formatSymphonyWorkerEnvironment(input.workspace.environment)}`] : []),
|
|
246
246
|
'',
|
|
247
247
|
'## Runtime Space Contract',
|
|
248
|
-
'- Shared control space: Issue
|
|
248
|
+
'- Shared control space: Idea/Issue/Report/Evidence are file-primary Pod resources with structured meta; Task, Delivery, Session, Run, and RunStep are TTL control resources. Use the provided URIs as the common coordination surface with AI Secretary and product UI.',
|
|
249
249
|
'- Explicit session topology: you may be collaborating in the same room as Secretary or running in a runtime-projected worker session reached through control events. Follow the provided chat/thread/session targets; do not infer topology from workspace sharing.',
|
|
250
250
|
'- Thread reconciliation: messages, input/approval requests, blockers, schedule ticks, and Delivery submissions enter the Thread first; the Reconciler/Scheduler wakes Secretary or workers.',
|
|
251
|
-
'- Report through Delivery/Evidence: return progress, blockers, implementation change requests, and verification
|
|
251
|
+
'- Report through Delivery plus file-primary Report/Evidence: return progress, blockers, implementation change requests, and verification so AI Secretary can persist structured control facts and Pod files without inlining long logs into TTL.',
|
|
252
252
|
'- Thread workspace: workers assigned to the same Thread in the same environment should normally share this workspace; independent Threads may use separate worktrees.',
|
|
253
253
|
'- Environment-scoped identity: cross-environment file identity requires revision, artifact, patch, checksum, or evidence references.',
|
|
254
254
|
'',
|
|
@@ -266,20 +266,21 @@ export function renderSymphonyRuntimePrompt(input) {
|
|
|
266
266
|
'- Report blockers to AI Secretary instead of asking the user directly.',
|
|
267
267
|
'- Do not read sibling worker transcripts unless Secretary explicitly includes them in a Delivery.',
|
|
268
268
|
'- Preserve a concise report with changed files, commands run, and remaining risks.',
|
|
269
|
+
'- In the final report, explicitly list follow-up candidates separately from assigned-work evidence: new defects, missing shared abstractions, app-local glue to move into shared models, storage, or adapter packages, live verification gaps, or deferred cleanup. Secretary classifies these; do not create or close Issues yourself.',
|
|
269
270
|
'- If blocked by missing credentials, destructive actions, or unclear scope, report the blocker instead of guessing.',
|
|
270
271
|
'- Your workspace path is local to this worker environment. Same-Thread workers in this environment may share it, but do not assume Secretary, the user, or workers in other environments can access the same absolute path.',
|
|
271
272
|
'- When reporting file work across environments, include repo-relative paths plus base revision, checksums/etags, patch or artifact references, and verification evidence.',
|
|
272
273
|
'',
|
|
273
274
|
'## Pod And Control Record Boundary',
|
|
274
275
|
'- In LinX runtime, Pod control records are authoritative. Local files are mirrors, logs, or portable-runtime fallbacks.',
|
|
275
|
-
'- If Pod/model tools are available, read only the assigned Issue, Task, Delivery, Run, source context, and existing
|
|
276
|
-
'- Write only execution facts for the assigned work: Run/RunStep progress, blockers, Evidence, Delivery report, or Implementation Change Request.',
|
|
276
|
+
'- If Pod/model tools are available, read only the assigned Issue document/meta, Task, Delivery, Run, source context, and existing Report/Evidence files needed for this task.',
|
|
277
|
+
'- Write only execution facts for the assigned work: Run/RunStep progress, blockers, file-primary Evidence/Report, Delivery report metadata, or Implementation Change Request.',
|
|
277
278
|
'- Do not close Issues, rewrite Spec/current truth, change acceptance criteria, change work split, alter release or roadmap state, create grants, or mutate sibling worker state.',
|
|
278
279
|
'- Use shared model/ORM surfaces when writing structured Pod data. Do not hand-patch business TTL or invent Pod paths.',
|
|
279
280
|
'- If Pod access is unavailable, return the same facts as a structured report so AI Secretary can persist them.',
|
|
280
281
|
'',
|
|
281
282
|
'## Documentation Authority',
|
|
282
|
-
'- Pod Issue
|
|
283
|
+
'- Pod Issue files plus meta, Spec files, and Task control records are the authority for status, scope, acceptance, split, ownership, closure, and cross-client coordination.',
|
|
283
284
|
'- Repository docs are the implementation authority for code-adjacent design, behavior notes, tests, examples, migration details, and file-level evidence.',
|
|
284
285
|
'- When you edit repository docs, reference the Pod Issue/Spec/Task URI instead of creating a second Issue truth.',
|
|
285
286
|
'- If repository findings contradict the Pod control record, write an Implementation Change Request instead of silently changing acceptance or scope.',
|
|
@@ -9,14 +9,12 @@
|
|
|
9
9
|
"./companion-model": "./dist/companion-model.js",
|
|
10
10
|
"./control-plane": "./dist/control-plane.js",
|
|
11
11
|
"./file-sync": "./dist/file-sync.js",
|
|
12
|
-
"./pod-resource-identity": "./dist/pod-resource-identity.js",
|
|
13
12
|
"./reconciler": "./dist/reconciler.js",
|
|
14
13
|
"./runtime": "./dist/runtime.js",
|
|
15
14
|
"./symphony": "./dist/symphony.js",
|
|
16
15
|
"./sync": "./dist/sync.js",
|
|
17
16
|
"./thread-reconciler-controller": "./dist/thread-reconciler-controller.js",
|
|
18
17
|
"./turn-controller": "./dist/turn-controller.js",
|
|
19
|
-
"./wake-scheduler": "./dist/wake-scheduler.js"
|
|
20
|
-
"./workspace": "./dist/workspace.js"
|
|
18
|
+
"./wake-scheduler": "./dist/wake-scheduler.js"
|
|
21
19
|
}
|
|
22
20
|
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { getClientCredentialId, getClientCredentialKey, getClientCredentials, loadCredentials, } from '../credentials-store.js';
|
|
2
|
-
import { getOidcAccessToken, isOidcLoginExpiredError } from '../oidc-auth.js';
|
|
3
|
-
import { getAccessToken } from '../solid-auth.js';
|
|
4
|
-
function isRuntimeOverride(value) {
|
|
5
|
-
return typeof value === 'object'
|
|
6
|
-
&& value !== null
|
|
7
|
-
&& ('loadCredentials' in value
|
|
8
|
-
|| 'getClientCredentials' in value
|
|
9
|
-
|| 'getAccessToken' in value
|
|
10
|
-
|| 'getOidcAccessToken' in value);
|
|
11
|
-
}
|
|
12
|
-
function resolveOidcExpiresAt(credentials) {
|
|
13
|
-
const expiresAt = 'oidcExpiresAt' in credentials.secrets
|
|
14
|
-
? new Date(credentials.secrets.oidcExpiresAt).getTime()
|
|
15
|
-
: NaN;
|
|
16
|
-
return Number.isFinite(expiresAt) ? expiresAt : Date.now();
|
|
17
|
-
}
|
|
18
|
-
export async function resolveLinxPiCloudOAuthCredential(issuerUrl, optionsOrRuntime = {}, runtimeArg) {
|
|
19
|
-
const defaultRuntime = {
|
|
20
|
-
loadCredentials,
|
|
21
|
-
getClientCredentials,
|
|
22
|
-
getAccessToken,
|
|
23
|
-
getOidcAccessToken,
|
|
24
|
-
};
|
|
25
|
-
const options = isRuntimeOverride(optionsOrRuntime)
|
|
26
|
-
? {}
|
|
27
|
-
: optionsOrRuntime;
|
|
28
|
-
const runtime = {
|
|
29
|
-
...defaultRuntime,
|
|
30
|
-
...(isRuntimeOverride(optionsOrRuntime) ? optionsOrRuntime : runtimeArg),
|
|
31
|
-
};
|
|
32
|
-
const stored = runtime.loadCredentials();
|
|
33
|
-
if (!stored) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
const clientCredentials = runtime.getClientCredentials(stored);
|
|
37
|
-
if (!clientCredentials) {
|
|
38
|
-
const oidcAccessToken = await runtime.getOidcAccessToken(stored, { forceRefresh: options.forceRefresh }).catch((error) => {
|
|
39
|
-
if (isOidcLoginExpiredError(error)) {
|
|
40
|
-
throw error;
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
});
|
|
44
|
-
if (!oidcAccessToken) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
type: 'oauth',
|
|
49
|
-
refresh: 'linx-oidc-refresh',
|
|
50
|
-
access: oidcAccessToken,
|
|
51
|
-
expires: resolveOidcExpiresAt(stored),
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
const resolvedIssuerUrl = issuerUrl?.trim() || stored.url;
|
|
55
|
-
const clientId = getClientCredentialId(clientCredentials);
|
|
56
|
-
const clientSecret = getClientCredentialKey(clientCredentials);
|
|
57
|
-
const token = await runtime.getAccessToken(clientId, clientSecret, resolvedIssuerUrl);
|
|
58
|
-
if (!token) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
return {
|
|
62
|
-
type: 'oauth',
|
|
63
|
-
refresh: clientSecret,
|
|
64
|
-
access: token.accessToken,
|
|
65
|
-
expires: token.expiresAt.getTime(),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/lib/pi-adapter/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pod Read/Write tools — LLM-facing tools for Pod filesystem access.
|
|
3
|
-
*
|
|
4
|
-
* These tools provide the LLM with the same familiar read/write interface
|
|
5
|
-
* as local files, but routed through the authenticated Pod HTTP API.
|
|
6
|
-
*
|
|
7
|
-
* The LLM should prefer these over local read/write when the path starts
|
|
8
|
-
* with a Pod root (e.g., /alice/). For local files, use read/write.
|
|
9
|
-
*/
|
|
10
|
-
import { Type } from 'typebox';
|
|
11
|
-
import { resolveLinxPodBaseUrl } from '@undefineds.co/models/client';
|
|
12
|
-
import { getDefaultPodDataSession } from '../pod-data-session.js';
|
|
13
|
-
// ── Parameter Schemas ──────────────────────────────────────────────────────
|
|
14
|
-
const PodReadParams = Type.Object({
|
|
15
|
-
path: Type.String({ description: 'Pod resource path (e.g., /alice/settings/credentials.ttl)' }),
|
|
16
|
-
});
|
|
17
|
-
const PodWriteParams = Type.Object({
|
|
18
|
-
path: Type.String({ description: 'Pod resource path (e.g., /alice/settings/credentials.ttl)' }),
|
|
19
|
-
content: Type.String({ description: 'Content to write' }),
|
|
20
|
-
contentType: Type.Optional(Type.String({ description: 'Content-Type header. Default: text/turtle for .ttl, text/markdown for .md, application/json for .json' })),
|
|
21
|
-
});
|
|
22
|
-
// ── Content-Type inference ──────────────────────────────────────────────────
|
|
23
|
-
function inferContentType(path) {
|
|
24
|
-
if (path.endsWith('.ttl'))
|
|
25
|
-
return 'text/turtle';
|
|
26
|
-
if (path.endsWith('.md'))
|
|
27
|
-
return 'text/markdown';
|
|
28
|
-
if (path.endsWith('.json'))
|
|
29
|
-
return 'application/json';
|
|
30
|
-
if (path.endsWith('.html'))
|
|
31
|
-
return 'text/html';
|
|
32
|
-
return 'text/plain';
|
|
33
|
-
}
|
|
34
|
-
export function resolvePodToolUrl(path, pod) {
|
|
35
|
-
if (/^https?:\/\//i.test(path)) {
|
|
36
|
-
return path;
|
|
37
|
-
}
|
|
38
|
-
const webId = pod.webId?.trim() ?? '';
|
|
39
|
-
const origin = resolveUrlOrigin(webId) || resolveUrlOrigin(pod.credentials?.url);
|
|
40
|
-
if (path.startsWith('/')) {
|
|
41
|
-
if (!origin) {
|
|
42
|
-
throw new Error('Cannot resolve absolute Pod path without a WebID or issuer URL.');
|
|
43
|
-
}
|
|
44
|
-
return new URL(path, `${origin}/`).toString();
|
|
45
|
-
}
|
|
46
|
-
const podBase = webId ? resolveLinxPodBaseUrl(webId) : '';
|
|
47
|
-
const baseUrl = podBase || origin;
|
|
48
|
-
if (!baseUrl) {
|
|
49
|
-
throw new Error('Cannot resolve relative Pod path without a WebID or issuer URL.');
|
|
50
|
-
}
|
|
51
|
-
return new URL(path, `${baseUrl.replace(/\/+$/, '')}/`).toString();
|
|
52
|
-
}
|
|
53
|
-
function resolveUrlOrigin(url) {
|
|
54
|
-
try {
|
|
55
|
-
return typeof url === 'string' && url.trim() ? new URL(url).origin : '';
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
return '';
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// ── Tool Definitions ────────────────────────────────────────────────────────
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
-
export const podReadTool = {
|
|
64
|
-
name: 'pod_read',
|
|
65
|
-
label: 'Pod Read',
|
|
66
|
-
description: [
|
|
67
|
-
'Read a file from the user\'s Pod. Use this for any path under the Pod root (e.g., /alice/...).',
|
|
68
|
-
'For local files, use the regular read tool instead.',
|
|
69
|
-
].join('\n'),
|
|
70
|
-
parameters: PodReadParams,
|
|
71
|
-
async execute(_callId, params) {
|
|
72
|
-
return executePodRead(params);
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
export async function executePodRead(params, getPodDataSession = getDefaultPodDataSession) {
|
|
76
|
-
const path = params.path.trim();
|
|
77
|
-
if (!path)
|
|
78
|
-
return { content: [{ type: 'text', text: 'Error: path is required' }], isError: true };
|
|
79
|
-
const pod = await getPodDataSession();
|
|
80
|
-
if (!pod)
|
|
81
|
-
return { content: [{ type: 'text', text: 'Error: not connected to Pod' }], isError: true };
|
|
82
|
-
try {
|
|
83
|
-
const fullUrl = resolvePodToolUrl(path, pod);
|
|
84
|
-
const res = await pod.fetch(fullUrl);
|
|
85
|
-
if (!res.ok) {
|
|
86
|
-
const body = await res.text().catch(() => '');
|
|
87
|
-
return { content: [{ type: 'text', text: `Pod read failed: HTTP ${res.status} — ${body.slice(0, 500)}` }], isError: true };
|
|
88
|
-
}
|
|
89
|
-
const text = await res.text();
|
|
90
|
-
return { content: [{ type: 'text', text }] };
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
return { content: [{ type: 'text', text: `Pod read error: ${e instanceof Error ? e.message : String(e)}` }], isError: true };
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
97
|
-
export const podWriteTool = {
|
|
98
|
-
name: 'pod_write',
|
|
99
|
-
label: 'Pod Write',
|
|
100
|
-
description: [
|
|
101
|
-
'Write content to a file in the user\'s Pod. Use this for any path under the Pod root (e.g., /alice/...).',
|
|
102
|
-
'Content-Type is inferred from the file extension (.ttl → text/turtle, .md → text/markdown, .json → application/json).',
|
|
103
|
-
'For local files, use the regular write tool instead.',
|
|
104
|
-
].join('\n'),
|
|
105
|
-
parameters: PodWriteParams,
|
|
106
|
-
async execute(_callId, params) {
|
|
107
|
-
return executePodWrite(params);
|
|
108
|
-
},
|
|
109
|
-
};
|
|
110
|
-
export async function executePodWrite(params, getPodDataSession = getDefaultPodDataSession) {
|
|
111
|
-
const path = params.path.trim();
|
|
112
|
-
if (!path)
|
|
113
|
-
return { content: [{ type: 'text', text: 'Error: path is required' }], isError: true };
|
|
114
|
-
const pod = await getPodDataSession();
|
|
115
|
-
if (!pod)
|
|
116
|
-
return { content: [{ type: 'text', text: 'Error: not connected to Pod' }], isError: true };
|
|
117
|
-
const ct = params.contentType?.trim() || inferContentType(path);
|
|
118
|
-
try {
|
|
119
|
-
const fullUrl = resolvePodToolUrl(path, pod);
|
|
120
|
-
const res = await pod.fetch(fullUrl, {
|
|
121
|
-
method: 'PUT',
|
|
122
|
-
headers: { 'Content-Type': ct },
|
|
123
|
-
body: params.content,
|
|
124
|
-
});
|
|
125
|
-
if (!res.ok) {
|
|
126
|
-
const body = await res.text().catch(() => '');
|
|
127
|
-
return { content: [{ type: 'text', text: `Pod write failed: HTTP ${res.status} — ${body.slice(0, 500)}` }], isError: true };
|
|
128
|
-
}
|
|
129
|
-
return { content: [{ type: 'text', text: `Written: ${path}` }] };
|
|
130
|
-
}
|
|
131
|
-
catch (e) {
|
|
132
|
-
return { content: [{ type: 'text', text: `Pod write error: ${e instanceof Error ? e.message : String(e)}` }], isError: true };
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
// ── Pi Extension ────────────────────────────────────────────────────────────
|
|
136
|
-
export default function (pi) {
|
|
137
|
-
pi.registerTool(podReadTool);
|
|
138
|
-
pi.registerTool(podWriteTool);
|
|
139
|
-
}
|
|
140
|
-
//# sourceMappingURL=pod-tools.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pod-tools.js","sourceRoot":"","sources":["../../../src/lib/pi-adapter/pod-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resource-identity.js","sourceRoot":"","sources":["../../src/lib/resource-identity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,eAAe,EACf,wBAAwB,GAEzB,MAAM,2CAA2C,CAAA"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
declare const baseRelativeResourceIdBrand: unique symbol;
|
|
2
|
-
declare const resourceIriBrand: unique symbol;
|
|
3
|
-
export type BaseRelativeResourceId = string & {
|
|
4
|
-
readonly [baseRelativeResourceIdBrand]: 'BaseRelativeResourceId';
|
|
5
|
-
};
|
|
6
|
-
export type ResourceIri = string & {
|
|
7
|
-
readonly [resourceIriBrand]: 'ResourceIri';
|
|
8
|
-
};
|
|
9
|
-
export declare function asBaseRelativeResourceId(value: string, label?: string): BaseRelativeResourceId;
|
|
10
|
-
export declare function asResourceIri(value: string, label?: string): ResourceIri;
|
|
11
|
-
export declare function requireRowResourceId(row: {
|
|
12
|
-
id?: string | null;
|
|
13
|
-
} | null | undefined, label?: string): BaseRelativeResourceId;
|
|
14
|
-
export declare function agentResourceId(key?: string | null): BaseRelativeResourceId;
|
|
15
|
-
export declare function agentKeyFromResourceId(resourceId: string): string;
|
|
16
|
-
export declare function agentHomeDirFromResourceId(resourceId: string): BaseRelativeResourceId;
|
|
17
|
-
export {};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const ABSOLUTE_IRI = /^[a-zA-Z][a-zA-Z\d+.-]*:/;
|
|
2
|
-
const AGENT_RESOURCE_ID = /^([A-Za-z0-9_.-]+)\/$/;
|
|
3
|
-
const AGENT_KEY = /^[A-Za-z0-9_.-]+$/;
|
|
4
|
-
export function asBaseRelativeResourceId(value, label = 'Resource id') {
|
|
5
|
-
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
6
|
-
throw new Error(`${label} must be a non-empty base-relative resource id.`);
|
|
7
|
-
}
|
|
8
|
-
const normalized = value.trim();
|
|
9
|
-
if (ABSOLUTE_IRI.test(normalized) || normalized.startsWith('/') || normalized.startsWith('//')) {
|
|
10
|
-
throw new Error(`${label} must be a base-relative resource id.`);
|
|
11
|
-
}
|
|
12
|
-
return normalized;
|
|
13
|
-
}
|
|
14
|
-
export function asResourceIri(value, label = 'Resource IRI') {
|
|
15
|
-
if (typeof value !== 'string' || value.trim().length === 0) {
|
|
16
|
-
throw new Error(`${label} must be a non-empty resource IRI.`);
|
|
17
|
-
}
|
|
18
|
-
const normalized = value.trim();
|
|
19
|
-
if (!ABSOLUTE_IRI.test(normalized)) {
|
|
20
|
-
throw new Error(`${label} must be a full resource IRI.`);
|
|
21
|
-
}
|
|
22
|
-
return normalized;
|
|
23
|
-
}
|
|
24
|
-
export function requireRowResourceId(row, label = 'Pod row') {
|
|
25
|
-
if (!row || typeof row.id !== 'string' || row.id.trim().length === 0) {
|
|
26
|
-
throw new Error(`${label} row is missing row.id.`);
|
|
27
|
-
}
|
|
28
|
-
return asBaseRelativeResourceId(row.id, `${label} row.id`);
|
|
29
|
-
}
|
|
30
|
-
function defaultAgentKey() {
|
|
31
|
-
return `agent_${Math.random().toString(36).slice(2, 12)}`;
|
|
32
|
-
}
|
|
33
|
-
export function agentResourceId(key) {
|
|
34
|
-
const raw = typeof key === 'string' ? key.trim() : '';
|
|
35
|
-
const value = raw || defaultAgentKey();
|
|
36
|
-
if (AGENT_RESOURCE_ID.test(value)) {
|
|
37
|
-
return asBaseRelativeResourceId(value, 'Agent resource id');
|
|
38
|
-
}
|
|
39
|
-
if (!AGENT_KEY.test(value)) {
|
|
40
|
-
throw new Error('Agent key must use letters, numbers, dot, underscore, or dash.');
|
|
41
|
-
}
|
|
42
|
-
return asBaseRelativeResourceId(`${value}/`, 'Agent resource id');
|
|
43
|
-
}
|
|
44
|
-
export function agentKeyFromResourceId(resourceId) {
|
|
45
|
-
const id = asBaseRelativeResourceId(resourceId, 'Agent resource id');
|
|
46
|
-
const match = id.match(AGENT_RESOURCE_ID);
|
|
47
|
-
if (!match?.[1]) {
|
|
48
|
-
throw new Error('Agent resource id must use {agentKey}/.');
|
|
49
|
-
}
|
|
50
|
-
return match[1];
|
|
51
|
-
}
|
|
52
|
-
export function agentHomeDirFromResourceId(resourceId) {
|
|
53
|
-
return asBaseRelativeResourceId(agentResourceId(agentKeyFromResourceId(resourceId)), 'Agent home dir');
|
|
54
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export type RuntimeWorkspaceKind = 'local-folder' | 'local-worktree' | 'pod-container';
|
|
2
|
-
export interface RuntimeWorkspaceInput {
|
|
3
|
-
workspaceKind?: unknown;
|
|
4
|
-
workspaceUri?: string | null;
|
|
5
|
-
repoPath?: string | null;
|
|
6
|
-
folderPath?: string | null;
|
|
7
|
-
baseRef?: string | null;
|
|
8
|
-
branch?: string | null;
|
|
9
|
-
}
|
|
10
|
-
export interface NormalizedRuntimeWorkspaceInput {
|
|
11
|
-
workspaceKind: RuntimeWorkspaceKind;
|
|
12
|
-
workspaceUri?: string;
|
|
13
|
-
repoPath?: string;
|
|
14
|
-
folderPath?: string;
|
|
15
|
-
baseRef: string;
|
|
16
|
-
branch?: string;
|
|
17
|
-
}
|
|
18
|
-
export interface NormalizeRuntimeWorkspaceOptions {
|
|
19
|
-
normalizeLocalPath?: (value?: string | null) => string;
|
|
20
|
-
defaultBaseRef?: string;
|
|
21
|
-
}
|
|
22
|
-
export interface RuntimeWorkspaceSessionLike {
|
|
23
|
-
cwd?: string | null;
|
|
24
|
-
repoPath?: string | null;
|
|
25
|
-
folderPath?: string | null;
|
|
26
|
-
workspaceUri?: string | null;
|
|
27
|
-
}
|
|
28
|
-
export declare function isRuntimeWorkspaceKind(value: unknown): value is RuntimeWorkspaceKind;
|
|
29
|
-
export declare function isHttpWorkspaceRef(value?: string | null): boolean;
|
|
30
|
-
export declare function inferRuntimeWorkspaceKind(input: RuntimeWorkspaceInput, options?: NormalizeRuntimeWorkspaceOptions): RuntimeWorkspaceKind;
|
|
31
|
-
export declare function normalizeRuntimeWorkspaceInput(input: RuntimeWorkspaceInput, options?: NormalizeRuntimeWorkspaceOptions): NormalizedRuntimeWorkspaceInput;
|
|
32
|
-
export declare function isRuntimeSessionInWorkspace(session: RuntimeWorkspaceSessionLike, workspacePath: string, options?: NormalizeRuntimeWorkspaceOptions): boolean;
|
|
33
|
-
export declare function filterRuntimeSessionsForWorkspace<T extends RuntimeWorkspaceSessionLike>(sessions: T[], workspacePath: string, options?: NormalizeRuntimeWorkspaceOptions): T[];
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
function trim(value) {
|
|
2
|
-
return value?.trim() || '';
|
|
3
|
-
}
|
|
4
|
-
function normalizeLocalPath(value) {
|
|
5
|
-
return trim(value);
|
|
6
|
-
}
|
|
7
|
-
export function isRuntimeWorkspaceKind(value) {
|
|
8
|
-
return value === 'local-folder' || value === 'local-worktree' || value === 'pod-container';
|
|
9
|
-
}
|
|
10
|
-
export function isHttpWorkspaceRef(value) {
|
|
11
|
-
const candidate = trim(value);
|
|
12
|
-
if (!candidate)
|
|
13
|
-
return false;
|
|
14
|
-
try {
|
|
15
|
-
const url = new URL(candidate);
|
|
16
|
-
return url.protocol === 'http:' || url.protocol === 'https:';
|
|
17
|
-
}
|
|
18
|
-
catch {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export function inferRuntimeWorkspaceKind(input, options = {}) {
|
|
23
|
-
if (isRuntimeWorkspaceKind(input.workspaceKind)) {
|
|
24
|
-
return input.workspaceKind;
|
|
25
|
-
}
|
|
26
|
-
const normalize = options.normalizeLocalPath ?? normalizeLocalPath;
|
|
27
|
-
const repoPath = normalize(input.repoPath);
|
|
28
|
-
if (isHttpWorkspaceRef(input.workspaceUri) && !repoPath) {
|
|
29
|
-
return 'pod-container';
|
|
30
|
-
}
|
|
31
|
-
const folderPath = normalize(input.folderPath);
|
|
32
|
-
return repoPath && folderPath && folderPath !== repoPath ? 'local-worktree' : 'local-folder';
|
|
33
|
-
}
|
|
34
|
-
export function normalizeRuntimeWorkspaceInput(input, options = {}) {
|
|
35
|
-
const normalize = options.normalizeLocalPath ?? normalizeLocalPath;
|
|
36
|
-
const workspaceKind = inferRuntimeWorkspaceKind(input, options);
|
|
37
|
-
const workspaceUri = trim(input.workspaceUri) || undefined;
|
|
38
|
-
const repoPath = normalize(input.repoPath) || undefined;
|
|
39
|
-
const folderPathInput = normalize(input.folderPath) || undefined;
|
|
40
|
-
const baseRef = trim(input.baseRef) || options.defaultBaseRef || 'HEAD';
|
|
41
|
-
const branch = trim(input.branch) || undefined;
|
|
42
|
-
if (workspaceKind === 'pod-container') {
|
|
43
|
-
if (!workspaceUri || !isHttpWorkspaceRef(workspaceUri)) {
|
|
44
|
-
throw new Error('Pod workspace session requires an http(s) workspaceUri.');
|
|
45
|
-
}
|
|
46
|
-
return {
|
|
47
|
-
workspaceKind,
|
|
48
|
-
workspaceUri,
|
|
49
|
-
repoPath,
|
|
50
|
-
folderPath: folderPathInput,
|
|
51
|
-
baseRef,
|
|
52
|
-
branch,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
if (!repoPath) {
|
|
56
|
-
throw new Error('Local runtime session requires repoPath.');
|
|
57
|
-
}
|
|
58
|
-
const folderPath = folderPathInput || repoPath;
|
|
59
|
-
return {
|
|
60
|
-
workspaceKind: folderPath !== repoPath ? 'local-worktree' : 'local-folder',
|
|
61
|
-
workspaceUri,
|
|
62
|
-
repoPath,
|
|
63
|
-
folderPath,
|
|
64
|
-
baseRef,
|
|
65
|
-
branch,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
export function isRuntimeSessionInWorkspace(session, workspacePath, options = {}) {
|
|
69
|
-
const normalize = options.normalizeLocalPath ?? normalizeLocalPath;
|
|
70
|
-
const expected = normalize(workspacePath);
|
|
71
|
-
if (!expected)
|
|
72
|
-
return false;
|
|
73
|
-
const candidates = [session.cwd, session.folderPath, session.repoPath]
|
|
74
|
-
.map((value) => normalize(value))
|
|
75
|
-
.filter(Boolean);
|
|
76
|
-
return candidates.some((candidate) => candidate === expected);
|
|
77
|
-
}
|
|
78
|
-
export function filterRuntimeSessionsForWorkspace(sessions, workspacePath, options = {}) {
|
|
79
|
-
return sessions.filter((session) => isRuntimeSessionInWorkspace(session, workspacePath, options));
|
|
80
|
-
}
|