@ours.network/fleet 1.2.0-nightly.67 → 1.2.0-nightly.68
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/build-info.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.2.0-nightly.
|
|
3
|
-
"buildId": "
|
|
4
|
-
"commit": "
|
|
2
|
+
"version": "1.2.0-nightly.68",
|
|
3
|
+
"buildId": "ec9481a2cd81",
|
|
4
|
+
"commit": "7c3095b817127cff76cac375f21e8124558e8f38",
|
|
5
5
|
"dirty": true,
|
|
6
|
-
"builtAt": "2026-10-
|
|
6
|
+
"builtAt": "2026-10-16T12:16:06.490Z",
|
|
7
7
|
"capabilities": [
|
|
8
8
|
"service.refresh-v1",
|
|
9
9
|
"managed-cli.codex-reasoning-effort-v1",
|
|
10
10
|
"managed-cli.setup-v1",
|
|
11
11
|
"workspace.enroll.preserve-profile-v1",
|
|
12
|
+
"workspace.enroll.optional-profile-v1",
|
|
12
13
|
"cowork.http-management-v1",
|
|
13
14
|
"monitor.interrupt.after_tool"
|
|
14
15
|
]
|
package/dist/capabilities.d.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
/** `monitor.interrupt: after_tool` — cancel at the next tool boundary (#67). */
|
|
16
16
|
export declare const CAP_MONITOR_INTERRUPT_AFTER_TOOL = "monitor.interrupt.after_tool";
|
|
17
17
|
export declare const CAP_HTTP_COWORK = "cowork.http-management-v1";
|
|
18
|
+
export declare const CAP_WORKSPACE_OPTIONAL_PROFILE = "workspace.enroll.optional-profile-v1";
|
|
18
19
|
export declare const CAP_WORKSPACE_PRESERVE_PROFILE = "workspace.enroll.preserve-profile-v1";
|
|
19
20
|
/** `ours-fleet managed-cli setup|status` and the `managed_cli` Agent key (#233). */
|
|
20
21
|
export declare const CAP_MANAGED_CLI_SETUP = "managed-cli.setup-v1";
|
|
@@ -22,7 +23,7 @@ export declare const CAP_MANAGED_CLI_SETUP = "managed-cli.setup-v1";
|
|
|
22
23
|
export declare const CAP_MANAGED_CLI_CODEX_EFFORT = "managed-cli.codex-reasoning-effort-v1";
|
|
23
24
|
/** `ours-fleet service check|refresh`: re-point service definitions after an update. */
|
|
24
25
|
export declare const CAP_SERVICE_REFRESH = "service.refresh-v1";
|
|
25
|
-
export declare const CAPABILITIES: readonly ["service.refresh-v1", "managed-cli.codex-reasoning-effort-v1", "managed-cli.setup-v1", "workspace.enroll.preserve-profile-v1", "cowork.http-management-v1", "monitor.interrupt.after_tool"];
|
|
26
|
+
export declare const CAPABILITIES: readonly ["service.refresh-v1", "managed-cli.codex-reasoning-effort-v1", "managed-cli.setup-v1", "workspace.enroll.preserve-profile-v1", "workspace.enroll.optional-profile-v1", "cowork.http-management-v1", "monitor.interrupt.after_tool"];
|
|
26
27
|
export type Capability = (typeof CAPABILITIES)[number];
|
|
27
28
|
/** Does this build declare `token`? */
|
|
28
29
|
export declare const hasCapability: (token: string) => boolean;
|
package/dist/capabilities.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
/** `monitor.interrupt: after_tool` — cancel at the next tool boundary (#67). */
|
|
16
16
|
export const CAP_MONITOR_INTERRUPT_AFTER_TOOL = 'monitor.interrupt.after_tool';
|
|
17
17
|
export const CAP_HTTP_COWORK = 'cowork.http-management-v1';
|
|
18
|
+
export const CAP_WORKSPACE_OPTIONAL_PROFILE = 'workspace.enroll.optional-profile-v1';
|
|
18
19
|
export const CAP_WORKSPACE_PRESERVE_PROFILE = 'workspace.enroll.preserve-profile-v1';
|
|
19
20
|
/** `ours-fleet managed-cli setup|status` and the `managed_cli` Agent key (#233). */
|
|
20
21
|
export const CAP_MANAGED_CLI_SETUP = 'managed-cli.setup-v1';
|
|
@@ -27,6 +28,7 @@ export const CAPABILITIES = [
|
|
|
27
28
|
CAP_MANAGED_CLI_CODEX_EFFORT,
|
|
28
29
|
CAP_MANAGED_CLI_SETUP,
|
|
29
30
|
CAP_WORKSPACE_PRESERVE_PROFILE,
|
|
31
|
+
CAP_WORKSPACE_OPTIONAL_PROFILE,
|
|
30
32
|
CAP_HTTP_COWORK,
|
|
31
33
|
CAP_MONITOR_INTERRUPT_AFTER_TOOL,
|
|
32
34
|
];
|
|
@@ -4,8 +4,9 @@ export interface WorkspacePayload {
|
|
|
4
4
|
appOrigin: string;
|
|
5
5
|
hostname: string;
|
|
6
6
|
rootName: string;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
fullName?: string | null;
|
|
8
|
+
name?: string | null;
|
|
9
|
+
surname?: string | null;
|
|
9
10
|
connectorToken?: string;
|
|
10
11
|
invitation: string;
|
|
11
12
|
serverCid: string;
|
|
@@ -25,14 +25,24 @@ export function decodeWorkspacePayload(input, options = {}) {
|
|
|
25
25
|
catch {
|
|
26
26
|
throw Error('Invalid workspace payload');
|
|
27
27
|
}
|
|
28
|
-
if (p.version !== 1 || !['https://app.ours.network', 'https://app.ours-tunnel.com'].includes(p.appOrigin) || !/^[a-z0-9][a-z0-9-]{2,60}\.ours-tunnel\.com$/.test(p.hostname) || !/^[a-z0-9-]{2,30}@[a-z0-9-]{2,30}$/.test(p.rootName) || !/^[a-f0-9]{64}$/i.test(p.serverCid) || !p.challenge || !['nonce', 'accountId', 'workspaceId'].every(k => /^[\w-]{43}$/.test(String(p.challenge[k]))) || (!options.allowExpired && p.challenge.expiresAt <= Date.now()) || !Number.isSafeInteger(p.challenge.expiresAt) || p.challenge.expiresAt > Date.now() + 16 * 60000)
|
|
28
|
+
if (!p || typeof p !== 'object' || Array.isArray(p) || p.version !== 1 || !['https://app.ours.network', 'https://app.ours-tunnel.com'].includes(p.appOrigin) || !/^[a-z0-9][a-z0-9-]{2,60}\.ours-tunnel\.com$/.test(p.hostname) || !/^[a-z0-9-]{2,30}@[a-z0-9-]{2,30}$/.test(p.rootName) || !/^[a-f0-9]{64}$/i.test(p.serverCid) || !p.challenge || !['nonce', 'accountId', 'workspaceId'].every(k => /^[\w-]{43}$/.test(String(p.challenge[k]))) || (!options.allowExpired && p.challenge.expiresAt <= Date.now()) || !Number.isSafeInteger(p.challenge.expiresAt) || p.challenge.expiresAt > Date.now() + 16 * 60000)
|
|
29
29
|
throw Error('Workspace payload is invalid or expired');
|
|
30
|
-
for (const k of ['connectorToken', 'invitation'
|
|
30
|
+
for (const k of ['connectorToken', 'invitation']) {
|
|
31
31
|
if (k === 'connectorToken' && p[k] === undefined)
|
|
32
32
|
continue;
|
|
33
33
|
if (typeof p[k] !== 'string' || !p[k] || p[k].length > 8192 || /[\x00-\x1f\x7f]/.test(p[k]))
|
|
34
34
|
throw Error('Invalid workspace payload');
|
|
35
35
|
}
|
|
36
|
+
for (const k of ['fullName', 'name', 'surname']) {
|
|
37
|
+
const value = p[k];
|
|
38
|
+
if (value == null || value === '') {
|
|
39
|
+
p[k] = null;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (typeof value !== 'string' || value.length > 8192 || /[\x00-\x1f\x7f]/.test(value))
|
|
43
|
+
throw Error('Invalid workspace profile');
|
|
44
|
+
p[k] = value.trim() || null;
|
|
45
|
+
}
|
|
36
46
|
return p;
|
|
37
47
|
}
|
|
38
48
|
/** Credential-free renewal is allowed only on the host already holding this private connector. */
|
|
@@ -120,11 +130,11 @@ const CID = /^[a-f0-9]{64}$/i, same = (a, b) => a.toLowerCase() === b.toLowerCas
|
|
|
120
130
|
async function messengerIdentity(request, attach) {
|
|
121
131
|
const bound = await request('workspace/enrollment-identity');
|
|
122
132
|
if (bound.rootCid === undefined)
|
|
123
|
-
return { cid: bound.cid, preserveProfile: bound.preserveProfile === true };
|
|
133
|
+
return { cid: bound.cid, preserveProfile: bound.preserveProfile === true, optionalWorkspaceProfileV1: bound.optionalWorkspaceProfileV1 === true };
|
|
124
134
|
if (typeof bound.cid !== 'string' || !CID.test(bound.cid) || typeof bound.rootCid !== 'string' || !CID.test(bound.rootCid) || same(bound.cid, bound.rootCid))
|
|
125
135
|
throw Error('Bound Messenger identity unavailable');
|
|
126
136
|
const root = await humanRoot(attach, bound.rootCid, bound.cid);
|
|
127
|
-
return { cid: bound.cid, preserveProfile: bound.preserveProfile === true, root };
|
|
137
|
+
return { cid: bound.cid, preserveProfile: bound.preserveProfile === true, optionalWorkspaceProfileV1: bound.optionalWorkspaceProfileV1 === true, root };
|
|
128
138
|
}
|
|
129
139
|
/** This host's only Human root, as its daemon lists it; optionally with a permanent identity that must be listed under it. */
|
|
130
140
|
async function humanRoot(attach, rootCid, under) {
|
|
@@ -280,6 +290,8 @@ export async function enrollWorkspace(payload, configuration = defaultConfigPath
|
|
|
280
290
|
&& (options.replacingWorkspace !== undefined || JSON.parse(readFileSync(previousFile, 'utf8')).serverCid?.toUpperCase() === payload.serverCid.toUpperCase());
|
|
281
291
|
if (options.preserveProfile && identity.preserveProfile !== true)
|
|
282
292
|
throw Error('Existing-host setup requires Messenger profile-preservation support; update the host Messenger before retrying');
|
|
293
|
+
if (!options.preserveProfile && (payload.fullName?.trim() || !payload.name?.trim() || !payload.surname?.trim()) && !identity.optionalWorkspaceProfileV1)
|
|
294
|
+
throw Error('Optional workspace profile requires updated Messenger; update the host Messenger before retrying (the host is not enrolled)');
|
|
283
295
|
if (loaded.rooms && !lost && !moved && loaded.rooms.owner.expected_cid.toLowerCase() !== identity.cid.toLowerCase())
|
|
284
296
|
throw Error('Retained room owner CID conflicts with the Human root');
|
|
285
297
|
const inviteFile = loaded.rooms?.owner.public_invite_file || join(dir, 'owner.invite');
|
|
@@ -291,7 +303,7 @@ export async function enrollWorkspace(payload, configuration = defaultConfigPath
|
|
|
291
303
|
const devices = new WorkspaceDeviceStore();
|
|
292
304
|
const hostWorkspaceId = devices.workspaceId;
|
|
293
305
|
devices.close();
|
|
294
|
-
const { name, surname, ...proofPayload } = payload;
|
|
306
|
+
const { fullName, name, surname, ...proofPayload } = payload;
|
|
295
307
|
let result, ownerCid;
|
|
296
308
|
// A replacement can stop after its one-time proof but before local files commit. Read the
|
|
297
309
|
// account's existing signed receipt first; a verified proof must not be sent a second time.
|
|
@@ -316,6 +328,8 @@ export async function enrollWorkspace(payload, configuration = defaultConfigPath
|
|
|
316
328
|
}
|
|
317
329
|
}
|
|
318
330
|
if (identity.root) {
|
|
331
|
+
if (!options.preserveProfile)
|
|
332
|
+
await request('identity/profile', { fullName: fullName ?? null, name: name ?? null, surname: surname ?? null });
|
|
319
333
|
// The Human root signs the binding; the person's own Messenger identity is the room Owner and issues the Owner invitation.
|
|
320
334
|
if (!proofAlreadyConfirmed)
|
|
321
335
|
await proveWithHumanRoot(attach, identity.root, payload, hostWorkspaceId, options.contactWaitMs ?? 10000, options.replacingWorkspace !== undefined);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ours.network/fleet",
|
|
3
|
-
"version": "1.2.0-nightly.
|
|
3
|
+
"version": "1.2.0-nightly.68",
|
|
4
4
|
"description": "Harness-agnostic fleet of persistent, identity-bound AI agents. Declarative fleet.yaml, managed native/ACP sessions, supervision, and ours.network messaging.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "FSL-1.1-Apache-2.0",
|