@dharma-ai-labs/agent-fabric 0.2.48 → 0.2.50
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/index.d.ts +92 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +846 -180
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +25 -3
- package/dist/index.test.js.map +1 -1
- package/dist/repositoryCandidateSync.d.ts +55 -0
- package/dist/repositoryCandidateSync.d.ts.map +1 -0
- package/dist/repositoryCandidateSync.js +177 -0
- package/dist/repositoryCandidateSync.js.map +1 -0
- package/dist/repositoryCandidateSync.test.d.ts +2 -0
- package/dist/repositoryCandidateSync.test.d.ts.map +1 -0
- package/dist/repositoryCandidateSync.test.js +141 -0
- package/dist/repositoryCandidateSync.test.js.map +1 -0
- package/dist/repositoryInstalledKnowledge.d.ts +13 -0
- package/dist/repositoryInstalledKnowledge.d.ts.map +1 -0
- package/dist/repositoryInstalledKnowledge.js +25 -0
- package/dist/repositoryInstalledKnowledge.js.map +1 -0
- package/dist/repositoryInstallerFiles.d.ts +6 -0
- package/dist/repositoryInstallerFiles.d.ts.map +1 -0
- package/dist/repositoryInstallerFiles.js +113 -0
- package/dist/repositoryInstallerFiles.js.map +1 -0
- package/dist/repositoryKnowledge.d.ts +119 -0
- package/dist/repositoryKnowledge.d.ts.map +1 -0
- package/dist/repositoryKnowledge.js +462 -0
- package/dist/repositoryKnowledge.js.map +1 -0
- package/dist/repositoryKnowledge.test.d.ts +2 -0
- package/dist/repositoryKnowledge.test.d.ts.map +1 -0
- package/dist/repositoryKnowledge.test.js +245 -0
- package/dist/repositoryKnowledge.test.js.map +1 -0
- package/dist/repositoryKnowledgeRetention.test.d.ts +2 -0
- package/dist/repositoryKnowledgeRetention.test.d.ts.map +1 -0
- package/dist/repositoryKnowledgeRetention.test.js +386 -0
- package/dist/repositoryKnowledgeRetention.test.js.map +1 -0
- package/dist/repositoryOnboardingCaller.test.d.ts +2 -0
- package/dist/repositoryOnboardingCaller.test.d.ts.map +1 -0
- package/dist/repositoryOnboardingCaller.test.js +197 -0
- package/dist/repositoryOnboardingCaller.test.js.map +1 -0
- package/dist/repositoryOnboardingFlow.test.d.ts +2 -0
- package/dist/repositoryOnboardingFlow.test.d.ts.map +1 -0
- package/dist/repositoryOnboardingFlow.test.js +47 -0
- package/dist/repositoryOnboardingFlow.test.js.map +1 -0
- package/dist/repositoryPackage.d.ts +115 -0
- package/dist/repositoryPackage.d.ts.map +1 -0
- package/dist/repositoryPackage.js +1095 -0
- package/dist/repositoryPackage.js.map +1 -0
- package/dist/repositoryPackage.test.d.ts +2 -0
- package/dist/repositoryPackage.test.d.ts.map +1 -0
- package/dist/repositoryPackage.test.js +709 -0
- package/dist/repositoryPackage.test.js.map +1 -0
- package/dist/repositoryPackageDelivery.d.ts +29 -0
- package/dist/repositoryPackageDelivery.d.ts.map +1 -0
- package/dist/repositoryPackageDelivery.js +140 -0
- package/dist/repositoryPackageDelivery.js.map +1 -0
- package/dist/repositoryPackageDelivery.test.d.ts +2 -0
- package/dist/repositoryPackageDelivery.test.d.ts.map +1 -0
- package/dist/repositoryPackageDelivery.test.js +787 -0
- package/dist/repositoryPackageDelivery.test.js.map +1 -0
- package/dist/repositoryPackageDeliveryCaller.test.d.ts +2 -0
- package/dist/repositoryPackageDeliveryCaller.test.d.ts.map +1 -0
- package/dist/repositoryPackageDeliveryCaller.test.js +18 -0
- package/dist/repositoryPackageDeliveryCaller.test.js.map +1 -0
- package/dist/repositoryPackageDeliveryPreflight.test.d.ts +2 -0
- package/dist/repositoryPackageDeliveryPreflight.test.d.ts.map +1 -0
- package/dist/repositoryPackageDeliveryPreflight.test.js +29 -0
- package/dist/repositoryPackageDeliveryPreflight.test.js.map +1 -0
- package/dist/repositoryPackageTransfer.d.ts +85 -0
- package/dist/repositoryPackageTransfer.d.ts.map +1 -0
- package/dist/repositoryPackageTransfer.js +233 -0
- package/dist/repositoryPackageTransfer.js.map +1 -0
- package/dist/repositoryPackageTransfer.test.d.ts +2 -0
- package/dist/repositoryPackageTransfer.test.d.ts.map +1 -0
- package/dist/repositoryPackageTransfer.test.js +173 -0
- package/dist/repositoryPackageTransfer.test.js.map +1 -0
- package/dist/repositoryPackageTransferV2.test.d.ts +2 -0
- package/dist/repositoryPackageTransferV2.test.d.ts.map +1 -0
- package/dist/repositoryPackageTransferV2.test.js +549 -0
- package/dist/repositoryPackageTransferV2.test.js.map +1 -0
- package/dist/repositoryPackageTransferV2Schema.test.d.ts +2 -0
- package/dist/repositoryPackageTransferV2Schema.test.d.ts.map +1 -0
- package/dist/repositoryPackageTransferV2Schema.test.js +48 -0
- package/dist/repositoryPackageTransferV2Schema.test.js.map +1 -0
- package/dist/repositoryReleaseMetadata.d.ts +37 -0
- package/dist/repositoryReleaseMetadata.d.ts.map +1 -0
- package/dist/repositoryReleaseMetadata.js +251 -0
- package/dist/repositoryReleaseMetadata.js.map +1 -0
- package/dist/repositoryReleaseMetadata.test.d.ts +2 -0
- package/dist/repositoryReleaseMetadata.test.d.ts.map +1 -0
- package/dist/repositoryReleaseMetadata.test.js +297 -0
- package/dist/repositoryReleaseMetadata.test.js.map +1 -0
- package/dist/repositoryRoleDerivation.d.ts +11 -0
- package/dist/repositoryRoleDerivation.d.ts.map +1 -0
- package/dist/repositoryRoleDerivation.js +59 -0
- package/dist/repositoryRoleDerivation.js.map +1 -0
- package/dist/repositoryRoleDerivation.test.d.ts +2 -0
- package/dist/repositoryRoleDerivation.test.d.ts.map +1 -0
- package/dist/repositoryRoleDerivation.test.js +33 -0
- package/dist/repositoryRoleDerivation.test.js.map +1 -0
- package/dist/repositoryRoleMetadata.d.ts +63 -0
- package/dist/repositoryRoleMetadata.d.ts.map +1 -0
- package/dist/repositoryRoleMetadata.js +203 -0
- package/dist/repositoryRoleMetadata.js.map +1 -0
- package/dist/repositoryRoleMetadata.test.d.ts +2 -0
- package/dist/repositoryRoleMetadata.test.d.ts.map +1 -0
- package/dist/repositoryRoleMetadata.test.js +296 -0
- package/dist/repositoryRoleMetadata.test.js.map +1 -0
- package/dist/repositoryRoleQuestion.d.ts +36 -0
- package/dist/repositoryRoleQuestion.d.ts.map +1 -0
- package/dist/repositoryRoleQuestion.js +68 -0
- package/dist/repositoryRoleQuestion.js.map +1 -0
- package/dist/repositoryRoleQuestion.test.d.ts +2 -0
- package/dist/repositoryRoleQuestion.test.d.ts.map +1 -0
- package/dist/repositoryRoleQuestion.test.js +66 -0
- package/dist/repositoryRoleQuestion.test.js.map +1 -0
- package/dist/repositorySourceAuthorization.d.ts +43 -0
- package/dist/repositorySourceAuthorization.d.ts.map +1 -0
- package/dist/repositorySourceAuthorization.js +164 -0
- package/dist/repositorySourceAuthorization.js.map +1 -0
- package/dist/repositorySourceCapture.test.d.ts +2 -0
- package/dist/repositorySourceCapture.test.d.ts.map +1 -0
- package/dist/repositorySourceCapture.test.js +303 -0
- package/dist/repositorySourceCapture.test.js.map +1 -0
- package/dist/repositorySourceSync.d.ts +54 -0
- package/dist/repositorySourceSync.d.ts.map +1 -0
- package/dist/repositorySourceSync.js +88 -0
- package/dist/repositorySourceSync.js.map +1 -0
- package/dist/repositorySourceSync.test.d.ts +2 -0
- package/dist/repositorySourceSync.test.d.ts.map +1 -0
- package/dist/repositorySourceSync.test.js +218 -0
- package/dist/repositorySourceSync.test.js.map +1 -0
- package/dist/schemas/repository-knowledge-retention-v1.schema.json +26 -0
- package/dist/schemas/repository-knowledge-v2.schema.json +74 -0
- package/dist/schemas/repository-knowledge.schema.json +63 -0
- package/dist/schemas/repository-package-chunk-v2.schema.json +15 -0
- package/dist/schemas/repository-package-chunk.schema.json +18 -0
- package/dist/schemas/repository-package-delivery-v1.schema.json +51 -0
- package/dist/schemas/repository-package-envelope-v1.schema.json +16 -0
- package/dist/schemas/repository-package-transfer-v2.schema.json +36 -0
- package/dist/schemas/repository-package-transfer.schema.json +34 -0
- package/dist/schemas/repository-package-v2.schema.json +491 -0
- package/dist/schemas/repository-package-v3.schema.json +36 -0
- package/dist/schemas/repository-package.schema.json +94 -0
- package/dist/schemas/repository-release-manifest.schema.json +34 -0
- package/dist/schemas/repository-role-metadata.schema.json +82 -0
- package/dist/schemas/skill-preparation-pointer-v1.schema.json +28 -0
- package/dist/schemas/skill-preparation-v1.schema.json +32 -0
- package/dist/skillPollResponse.test.d.ts +2 -0
- package/dist/skillPollResponse.test.d.ts.map +1 -0
- package/dist/skillPollResponse.test.js +37 -0
- package/dist/skillPollResponse.test.js.map +1 -0
- package/dist/skillPreparation.test.d.ts +2 -0
- package/dist/skillPreparation.test.d.ts.map +1 -0
- package/dist/skillPreparation.test.js +163 -0
- package/dist/skillPreparation.test.js.map +1 -0
- package/dist/skillPreparationCache.d.ts +34 -0
- package/dist/skillPreparationCache.d.ts.map +1 -0
- package/dist/skillPreparationCache.js +371 -0
- package/dist/skillPreparationCache.js.map +1 -0
- package/dist/skillPreparationCache.test.d.ts +2 -0
- package/dist/skillPreparationCache.test.d.ts.map +1 -0
- package/dist/skillPreparationCache.test.js +316 -0
- package/dist/skillPreparationCache.test.js.map +1 -0
- package/dist/skillPreparationCaller.test.d.ts +2 -0
- package/dist/skillPreparationCaller.test.d.ts.map +1 -0
- package/dist/skillPreparationCaller.test.js +32 -0
- package/dist/skillPreparationCaller.test.js.map +1 -0
- package/dist/skillPreparationPump.d.ts +11 -0
- package/dist/skillPreparationPump.d.ts.map +1 -0
- package/dist/skillPreparationPump.js +41 -0
- package/dist/skillPreparationPump.js.map +1 -0
- package/dist/skillPreparationPump.test.d.ts +2 -0
- package/dist/skillPreparationPump.test.d.ts.map +1 -0
- package/dist/skillPreparationPump.test.js +87 -0
- package/dist/skillPreparationPump.test.js.map +1 -0
- package/dist/skillPreparationRecord.d.ts +2 -0
- package/dist/skillPreparationRecord.d.ts.map +1 -0
- package/dist/skillPreparationRecord.js +36 -0
- package/dist/skillPreparationRecord.js.map +1 -0
- package/dist/skillPreparationTransaction.d.ts +13 -0
- package/dist/skillPreparationTransaction.d.ts.map +1 -0
- package/dist/skillPreparationTransaction.js +236 -0
- package/dist/skillPreparationTransaction.js.map +1 -0
- package/dist/skillPreparationTransaction.test.d.ts +2 -0
- package/dist/skillPreparationTransaction.test.d.ts.map +1 -0
- package/dist/skillPreparationTransaction.test.js +181 -0
- package/dist/skillPreparationTransaction.test.js.map +1 -0
- package/dist/skillSyncPolicy.test.d.ts +2 -0
- package/dist/skillSyncPolicy.test.d.ts.map +1 -0
- package/dist/skillSyncPolicy.test.js +156 -0
- package/dist/skillSyncPolicy.test.js.map +1 -0
- package/dist/usage.d.ts +1 -1
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +1 -1
- package/dist/usage.js.map +1 -1
- package/dist/windowsProcessPortability.test.d.ts +2 -0
- package/dist/windowsProcessPortability.test.d.ts.map +1 -0
- package/dist/windowsProcessPortability.test.js +14 -0
- package/dist/windowsProcessPortability.test.js.map +1 -0
- package/package.json +7 -4
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { lstat } from 'node:fs/promises';
|
|
2
|
+
import { type ProviderId } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
3
|
+
export declare function assertWindowsSkillPreparationAcl(value: unknown): void;
|
|
4
|
+
export declare function assertPrivatePath(path: string, stat: Awaited<ReturnType<typeof lstat>>): Promise<void>;
|
|
5
|
+
export declare function skillPreparationScopeRoot(home: string, workspaceId: string, provider: string): string;
|
|
6
|
+
export declare function withSkillPreparationTransaction<T>(input: {
|
|
7
|
+
home: string;
|
|
8
|
+
workspaceId: string;
|
|
9
|
+
provider: ProviderId;
|
|
10
|
+
assertCurrent: () => void;
|
|
11
|
+
timeoutMs?: number;
|
|
12
|
+
}, operation: (scopeRoot: string) => Promise<T>): Promise<T>;
|
|
13
|
+
//# sourceMappingURL=skillPreparationTransaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillPreparationTransaction.d.ts","sourceRoot":"","sources":["../src/skillPreparationTransaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAe,MAAM,kBAAkB,CAAC;AAItD,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,wCAAwC,CAAC;AA4C/F,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAqBrE;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5G;AAkCD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMrG;AAqBD,wBAAsB,+BAA+B,CAAC,CAAC,EAAE,KAAK,EAAE;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,CAAC;IACrB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,EAAE,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAwD3D"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { constants, lstatSync, realpathSync } from 'node:fs';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { lstat, mkdir, open } from 'node:fs/promises';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { parse, relative, resolve, sep } from 'node:path';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { canonicalize, sha256 } from '@dharma-ai-labs/agent-fabric-contracts';
|
|
8
|
+
const UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-[1-8][a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$(?![\s\S])/;
|
|
9
|
+
const PROVIDERS = ['codex', 'claude', 'agy', 'hermes'];
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
const execFileAsync = promisify(execFile);
|
|
12
|
+
const WINDOWS_ACL_TIMEOUT_MS = 15000;
|
|
13
|
+
const ACL_SCRIPT = `$ErrorActionPreference='Stop';
|
|
14
|
+
$path=[Environment]::GetEnvironmentVariable('DHARMA_PREPARATION_ACL_PATH');
|
|
15
|
+
$acl=[System.IO.DirectoryInfo]::new($path).GetAccessControl();
|
|
16
|
+
$descriptor=[System.Security.AccessControl.RawSecurityDescriptor]::new($acl.GetSecurityDescriptorBinaryForm(),0);
|
|
17
|
+
$rules=@($acl.GetAccessRules($true,$true,[System.Security.Principal.SecurityIdentifier]) |
|
|
18
|
+
Where-Object { $_.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow } |
|
|
19
|
+
ForEach-Object { @{sid=$_.IdentityReference.Value;rights=[int64]$_.FileSystemRights;
|
|
20
|
+
inheritOnly=(($_.PropagationFlags -band [System.Security.AccessControl.PropagationFlags]::InheritOnly) -ne 0)} });
|
|
21
|
+
@{currentUserSid=[System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value;
|
|
22
|
+
ownerSid=$acl.GetOwner([System.Security.Principal.SecurityIdentifier]).Value;allowRules=$rules;
|
|
23
|
+
daclPresent=(($descriptor.ControlFlags -band [System.Security.AccessControl.ControlFlags]::DiscretionaryAclPresent) -ne 0);
|
|
24
|
+
daclNull=($null -eq $descriptor.DiscretionaryAcl)} |
|
|
25
|
+
ConvertTo-Json -Depth 4 -Compress`;
|
|
26
|
+
const PRIVATE_DIRECTORY_ACL_SCRIPT = `$ErrorActionPreference='Stop';
|
|
27
|
+
$path=[Environment]::GetEnvironmentVariable('DHARMA_PREPARATION_ACL_PATH');
|
|
28
|
+
$current=[System.Security.Principal.WindowsIdentity]::GetCurrent().User;
|
|
29
|
+
$acl=[System.Security.AccessControl.DirectorySecurity]::new();
|
|
30
|
+
$acl.SetOwner($current);
|
|
31
|
+
$acl.SetAccessRuleProtection($true,$false);
|
|
32
|
+
$inherit=[System.Security.AccessControl.InheritanceFlags]::ContainerInherit -bor
|
|
33
|
+
[System.Security.AccessControl.InheritanceFlags]::ObjectInherit;
|
|
34
|
+
$propagation=[System.Security.AccessControl.PropagationFlags]::None;
|
|
35
|
+
foreach($sid in @($current,[System.Security.Principal.SecurityIdentifier]::new('S-1-5-18'),
|
|
36
|
+
[System.Security.Principal.SecurityIdentifier]::new('S-1-5-32-544'))){
|
|
37
|
+
$rule=[System.Security.AccessControl.FileSystemAccessRule]::new($sid,
|
|
38
|
+
[System.Security.AccessControl.FileSystemRights]::FullControl,$inherit,$propagation,
|
|
39
|
+
[System.Security.AccessControl.AccessControlType]::Allow);
|
|
40
|
+
[void]$acl.AddAccessRule($rule);
|
|
41
|
+
}
|
|
42
|
+
[System.IO.DirectoryInfo]::new($path).SetAccessControl($acl)`;
|
|
43
|
+
function powershellEnvironment(path) {
|
|
44
|
+
return { SystemRoot: process.env.SystemRoot, PATH: process.env.PATH,
|
|
45
|
+
TEMP: process.env.TEMP, TMP: process.env.TMP, PSModulePath: process.env.PSModulePath,
|
|
46
|
+
DHARMA_PREPARATION_ACL_PATH: path };
|
|
47
|
+
}
|
|
48
|
+
export function assertWindowsSkillPreparationAcl(value) {
|
|
49
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
50
|
+
throw new Error('Invalid Windows preparation ACL.');
|
|
51
|
+
const acl = value;
|
|
52
|
+
const sid = (value) => typeof value === 'string' && /^S-1-[0-9-]{1,160}$(?![\s\S])/.test(value);
|
|
53
|
+
if (!sid(acl.currentUserSid) || !sid(acl.ownerSid) || acl.daclPresent !== true || acl.daclNull !== false
|
|
54
|
+
|| !Array.isArray(acl.allowRules) || acl.allowRules.length > 128) {
|
|
55
|
+
throw new Error('Invalid Windows preparation ACL.');
|
|
56
|
+
}
|
|
57
|
+
const trusted = new Set([acl.currentUserSid, 'S-1-5-18', 'S-1-5-32-544']);
|
|
58
|
+
if (!trusted.has(acl.ownerSid))
|
|
59
|
+
throw new Error('Windows preparation path is not privately owned.');
|
|
60
|
+
const harmless = 8 | 32 | 128 | 131072 | 1048576;
|
|
61
|
+
for (const value of acl.allowRules) {
|
|
62
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
63
|
+
throw new Error('Invalid Windows preparation ACL rule.');
|
|
64
|
+
const row = value;
|
|
65
|
+
if (!sid(row.sid) || !Number.isSafeInteger(row.rights) || row.rights < 0
|
|
66
|
+
|| row.rights > 2147483647 || typeof row.inheritOnly !== 'boolean')
|
|
67
|
+
throw new Error('Invalid Windows preparation ACL rule.');
|
|
68
|
+
const creatorOwner = row.sid === 'S-1-3-0' && row.inheritOnly === true;
|
|
69
|
+
if (!trusted.has(row.sid) && !creatorOwner && (row.rights & ~harmless) !== 0) {
|
|
70
|
+
throw new Error('Windows preparation path is not private.');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export async function assertPrivatePath(path, stat) {
|
|
75
|
+
if (process.platform !== 'win32') {
|
|
76
|
+
const getuid = process.getuid;
|
|
77
|
+
if (typeof getuid !== 'function' || typeof stat.uid !== 'number' || typeof stat.mode !== 'number'
|
|
78
|
+
|| stat.uid !== getuid() || (stat.mode & 0o077) !== 0) {
|
|
79
|
+
throw new Error('Skill preparation path must be privately owned.');
|
|
80
|
+
}
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const { stdout } = await execFileAsync('powershell.exe', ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', ACL_SCRIPT], {
|
|
85
|
+
windowsHide: true, timeout: WINDOWS_ACL_TIMEOUT_MS, maxBuffer: 65536,
|
|
86
|
+
env: powershellEnvironment(path),
|
|
87
|
+
});
|
|
88
|
+
assertWindowsSkillPreparationAcl(JSON.parse(stdout.replace(/^\uFEFF/, '')));
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
throw new Error('Windows preparation private access could not be verified.');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function hardenWindowsPrivateDirectory(path) {
|
|
95
|
+
if (process.platform !== 'win32')
|
|
96
|
+
return;
|
|
97
|
+
try {
|
|
98
|
+
await execFileAsync('powershell.exe', ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', PRIVATE_DIRECTORY_ACL_SCRIPT], {
|
|
99
|
+
windowsHide: true, timeout: WINDOWS_ACL_TIMEOUT_MS, maxBuffer: 65536, env: powershellEnvironment(path),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
throw new Error('Windows preparation private access could not be established.');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function canonicalExistingHome(path) {
|
|
107
|
+
const resolved = resolve(path);
|
|
108
|
+
try {
|
|
109
|
+
const stat = lstatSync(resolved);
|
|
110
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
111
|
+
return resolved;
|
|
112
|
+
return realpathSync.native(resolved);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
if (error.code === 'ENOENT')
|
|
116
|
+
return resolved;
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function preflightAncestors(path) {
|
|
121
|
+
let current = parse(resolve(path)).root;
|
|
122
|
+
for (const part of relative(current, resolve(path)).split(sep).filter(Boolean)) {
|
|
123
|
+
current = resolve(current, part);
|
|
124
|
+
try {
|
|
125
|
+
const stat = await lstat(current);
|
|
126
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
127
|
+
throw new Error('Skill preparation ancestor is not a real directory.');
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error.code === 'ENOENT')
|
|
131
|
+
return;
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function skillPreparationScopeRoot(home, workspaceId, provider) {
|
|
137
|
+
if (!home || !UUID.test(workspaceId) || !PROVIDERS.includes(provider)) {
|
|
138
|
+
throw new Error('Skill preparation requires a canonical workspace and supported provider.');
|
|
139
|
+
}
|
|
140
|
+
const key = sha256(canonicalize({ schema: 'dharma.skill-preparation-scope/v1', workspaceId, provider })).slice(7);
|
|
141
|
+
return resolve(canonicalExistingHome(home), 'relay', 'skill-pending-sources', key);
|
|
142
|
+
}
|
|
143
|
+
async function ensureDirectory(path) {
|
|
144
|
+
await mkdir(path, { recursive: true, mode: 0o700 });
|
|
145
|
+
const stat = await lstat(path);
|
|
146
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
147
|
+
throw new Error('Skill preparation directory is not an owned real directory.');
|
|
148
|
+
if (process.platform === 'win32') {
|
|
149
|
+
try {
|
|
150
|
+
await assertPrivatePath(path, stat);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
await hardenWindowsPrivateDirectory(path);
|
|
155
|
+
const hardened = await lstat(path);
|
|
156
|
+
if (!hardened.isDirectory() || hardened.isSymbolicLink()) {
|
|
157
|
+
throw new Error('Skill preparation directory is not an owned real directory.');
|
|
158
|
+
}
|
|
159
|
+
await assertPrivatePath(path, hardened);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
await assertPrivatePath(path, stat);
|
|
164
|
+
}
|
|
165
|
+
export async function withSkillPreparationTransaction(input, operation) {
|
|
166
|
+
const home = canonicalExistingHome(input.home);
|
|
167
|
+
const root = skillPreparationScopeRoot(home, input.workspaceId, input.provider);
|
|
168
|
+
const timeout = input.timeoutMs ?? 30000;
|
|
169
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 30000)
|
|
170
|
+
throw new Error('Invalid skill preparation lock wait.');
|
|
171
|
+
input.assertCurrent();
|
|
172
|
+
await preflightAncestors(home);
|
|
173
|
+
input.assertCurrent();
|
|
174
|
+
for (const path of [home, resolve(home, 'relay'), resolve(home, 'relay', 'skill-pending-sources'), root]) {
|
|
175
|
+
await ensureDirectory(path);
|
|
176
|
+
input.assertCurrent();
|
|
177
|
+
}
|
|
178
|
+
// Permanent inode: never unlink or rename this file, including after a crash.
|
|
179
|
+
const path = resolve(root, '.LOCK');
|
|
180
|
+
try {
|
|
181
|
+
const prior = await lstat(path);
|
|
182
|
+
if (!prior.isFile() || prior.isSymbolicLink() || prior.nlink !== 1)
|
|
183
|
+
throw new Error('Invalid skill preparation lock file.');
|
|
184
|
+
await assertPrivatePath(path, prior);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
if (error.code !== 'ENOENT')
|
|
188
|
+
throw error;
|
|
189
|
+
}
|
|
190
|
+
input.assertCurrent();
|
|
191
|
+
const file = await open(path, constants.O_RDWR | constants.O_CREAT | (constants.O_NOFOLLOW || 0), 0o600);
|
|
192
|
+
let acquired = false;
|
|
193
|
+
let native;
|
|
194
|
+
try {
|
|
195
|
+
const held = await file.stat();
|
|
196
|
+
await assertPrivatePath(path, held);
|
|
197
|
+
const assertStableName = async () => {
|
|
198
|
+
const current = await lstat(path);
|
|
199
|
+
if (!held.isFile() || held.nlink !== 1 || !current.isFile() || current.isSymbolicLink()
|
|
200
|
+
|| current.dev !== held.dev || current.ino !== held.ino || current.nlink !== 1) {
|
|
201
|
+
throw new Error('Skill preparation lock identity changed.');
|
|
202
|
+
}
|
|
203
|
+
input.assertCurrent();
|
|
204
|
+
};
|
|
205
|
+
await assertStableName();
|
|
206
|
+
// Missing addon or unsupported locking fails closed; no stale-PID fallback.
|
|
207
|
+
native = require('fs-native-extensions');
|
|
208
|
+
if (!native || typeof native.tryLock !== 'function' || typeof native.unlock !== 'function') {
|
|
209
|
+
throw new Error('Native skill preparation locking is unavailable.');
|
|
210
|
+
}
|
|
211
|
+
const deadline = Date.now() + timeout;
|
|
212
|
+
while (!acquired) {
|
|
213
|
+
input.assertCurrent();
|
|
214
|
+
acquired = native.tryLock(file.fd);
|
|
215
|
+
if (acquired)
|
|
216
|
+
break;
|
|
217
|
+
if (Date.now() >= deadline)
|
|
218
|
+
throw new Error('Skill preparation lock was not granted within the wait limit.');
|
|
219
|
+
await new Promise(resolveWait => setTimeout(resolveWait, 25));
|
|
220
|
+
}
|
|
221
|
+
await assertStableName();
|
|
222
|
+
const result = await operation(root);
|
|
223
|
+
await assertStableName();
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
finally {
|
|
227
|
+
try {
|
|
228
|
+
if (acquired)
|
|
229
|
+
native.unlock(file.fd);
|
|
230
|
+
}
|
|
231
|
+
finally {
|
|
232
|
+
await file.close();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=skillPreparationTransaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillPreparationTransaction.js","sourceRoot":"","sources":["../src/skillPreparationTransaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillPreparationTransaction.test.d.ts","sourceRoot":"","sources":["../src/skillPreparationTransaction.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { chmod, mkdir, mkdtemp, readFile, readdir, rm, stat, symlink } from 'node:fs/promises';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import test from 'node:test';
|
|
7
|
+
import { assertWindowsSkillPreparationAcl, skillPreparationScopeRoot, withSkillPreparationTransaction } from './skillPreparationTransaction.js';
|
|
8
|
+
const WORKSPACE = '11111111-1111-4111-8111-111111111111';
|
|
9
|
+
test('Windows preparation ACL policy rejects foreign read/write/owner grants and malformed output', () => {
|
|
10
|
+
const user = 'S-1-5-21-100-200-300-1000';
|
|
11
|
+
const rules = [user, 'S-1-5-18', 'S-1-5-32-544'].map(sid => ({ sid, rights: 2032127, inheritOnly: false }));
|
|
12
|
+
const acl = { currentUserSid: user, ownerSid: user, daclPresent: true, daclNull: false, allowRules: rules };
|
|
13
|
+
assert.doesNotThrow(() => assertWindowsSkillPreparationAcl(acl));
|
|
14
|
+
assert.doesNotThrow(() => assertWindowsSkillPreparationAcl({ ...acl, allowRules: [...rules, { sid: 'S-1-3-0', rights: 2032127, inheritOnly: true }] }));
|
|
15
|
+
for (const rights of [1, 2, 4, 16, 64, 256, 65536, 262144, 524288, 0x10000000, 0x40000000, 0x01000000]) {
|
|
16
|
+
assert.throws(() => assertWindowsSkillPreparationAcl({ ...acl,
|
|
17
|
+
allowRules: [...rules, { sid: 'S-1-5-32-545', rights, inheritOnly: false }] }), /private/);
|
|
18
|
+
}
|
|
19
|
+
assert.throws(() => assertWindowsSkillPreparationAcl({ ...acl, ownerSid: 'S-1-5-21-900-900-900-1000' }), /privately owned/);
|
|
20
|
+
assert.throws(() => assertWindowsSkillPreparationAcl({ ...acl, allowRules: [{ sid: user, rights: 'full', inheritOnly: false }] }), /Invalid/);
|
|
21
|
+
assert.throws(() => assertWindowsSkillPreparationAcl({ ...acl, allowRules: [{ sid: user, rights: -1, inheritOnly: false }] }), /Invalid/);
|
|
22
|
+
assert.throws(() => assertWindowsSkillPreparationAcl({ ...acl, allowRules: {} }), /Invalid/);
|
|
23
|
+
for (const flags of [{ daclPresent: false }, { daclNull: true }, { daclPresent: undefined }, { daclNull: 'false' }]) {
|
|
24
|
+
assert.throws(() => assertWindowsSkillPreparationAcl({ ...acl, ...flags, allowRules: [] }), /Invalid/);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
test('preparation ownership excludes concurrent transactions and keeps a permanent lock inode', async () => {
|
|
28
|
+
const home = await mkdtemp(join(tmpdir(), 'af-preparation-lock-'));
|
|
29
|
+
let release, entered;
|
|
30
|
+
const blocked = new Promise(resolve => { release = resolve; });
|
|
31
|
+
const started = new Promise(resolve => { entered = resolve; });
|
|
32
|
+
const input = { home, workspaceId: WORKSPACE, provider: 'codex', assertCurrent: () => { } };
|
|
33
|
+
const owner = withSkillPreparationTransaction(input, async () => { entered(); await blocked; });
|
|
34
|
+
try {
|
|
35
|
+
await Promise.race([started, owner.then(() => { throw new Error('Owner ended before entering.'); })]);
|
|
36
|
+
const before = await stat(join(skillPreparationScopeRoot(home, WORKSPACE, 'codex'), '.LOCK'));
|
|
37
|
+
let unauthorized = false;
|
|
38
|
+
await assert.rejects(withSkillPreparationTransaction({ ...input, timeoutMs: 50 }, async () => { unauthorized = true; }), /not granted/);
|
|
39
|
+
assert.equal(unauthorized, false);
|
|
40
|
+
await withSkillPreparationTransaction({ ...input, provider: 'claude' }, async () => { });
|
|
41
|
+
release();
|
|
42
|
+
await owner;
|
|
43
|
+
await withSkillPreparationTransaction(input, async () => { });
|
|
44
|
+
const after = await stat(join(skillPreparationScopeRoot(home, WORKSPACE, 'codex'), '.LOCK'));
|
|
45
|
+
assert.equal(after.ino, before.ino);
|
|
46
|
+
assert.equal(after.dev, before.dev);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
release();
|
|
50
|
+
await owner.catch(() => { });
|
|
51
|
+
await rm(home, { recursive: true, force: true });
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
test('stop does not release ownership before underlying preparation settles', async () => {
|
|
55
|
+
const home = await mkdtemp(join(tmpdir(), 'af-preparation-stop-'));
|
|
56
|
+
let stopped = false, release, entered;
|
|
57
|
+
const blocked = new Promise(resolve => { release = resolve; });
|
|
58
|
+
const started = new Promise(resolve => { entered = resolve; });
|
|
59
|
+
const input = { home, workspaceId: WORKSPACE, provider: 'codex',
|
|
60
|
+
assertCurrent: () => { if (stopped)
|
|
61
|
+
throw new Error('fixture stopped'); } };
|
|
62
|
+
const owner = withSkillPreparationTransaction(input, async () => { entered(); await blocked; });
|
|
63
|
+
const settled = owner.then(() => null, error => error);
|
|
64
|
+
try {
|
|
65
|
+
await Promise.race([started, settled.then(error => { throw error || new Error('Owner did not enter.'); })]);
|
|
66
|
+
stopped = true;
|
|
67
|
+
await assert.rejects(withSkillPreparationTransaction({ ...input, assertCurrent: () => { }, timeoutMs: 50 }, async () => { }), /not granted/);
|
|
68
|
+
release();
|
|
69
|
+
assert.match((await settled).message, /fixture stopped/);
|
|
70
|
+
await withSkillPreparationTransaction({ ...input, assertCurrent: () => { } }, async () => { });
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
release();
|
|
74
|
+
await settled;
|
|
75
|
+
await rm(home, { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
test('a symlinked preparation ancestor is rejected before locking or callback execution', async () => {
|
|
79
|
+
const home = await mkdtemp(join(tmpdir(), 'af-preparation-parent-'));
|
|
80
|
+
const foreign = await mkdtemp(join(tmpdir(), 'af-preparation-foreign-'));
|
|
81
|
+
try {
|
|
82
|
+
await symlink(foreign, join(home, 'relay'), process.platform === 'win32' ? 'junction' : 'dir');
|
|
83
|
+
let entered = false;
|
|
84
|
+
await assert.rejects(withSkillPreparationTransaction({ home, workspaceId: WORKSPACE, provider: 'codex', assertCurrent: () => { } }, async () => { entered = true; }), /real directory/);
|
|
85
|
+
assert.equal(entered, false);
|
|
86
|
+
assert.deepEqual(await import('node:fs/promises').then(fs => fs.readdir(foreign)), []);
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
await rm(home, { recursive: true, force: true });
|
|
90
|
+
await rm(foreign, { recursive: true, force: true });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
test('ancestors above the configured home are checked before recursive creation', async () => {
|
|
94
|
+
const owned = await mkdtemp(join(tmpdir(), 'af-preparation-above-'));
|
|
95
|
+
const foreign = await mkdtemp(join(tmpdir(), 'af-preparation-target-'));
|
|
96
|
+
try {
|
|
97
|
+
await symlink(foreign, join(owned, 'link'), process.platform === 'win32' ? 'junction' : 'dir');
|
|
98
|
+
await assert.rejects(withSkillPreparationTransaction({ home: join(owned, 'link', 'new-home'),
|
|
99
|
+
workspaceId: WORKSPACE, provider: 'codex', assertCurrent: () => { } }, async () => { }), /ancestor/);
|
|
100
|
+
assert.deepEqual(await readdir(foreign), []);
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
await rm(owned, { recursive: true, force: true });
|
|
104
|
+
await rm(foreign, { recursive: true, force: true });
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
test('existing non-private preparation directories are rejected without permission repair', { skip: process.platform === 'win32' }, async () => {
|
|
108
|
+
const home = await mkdtemp(join(tmpdir(), 'af-preparation-mode-'));
|
|
109
|
+
try {
|
|
110
|
+
const root = skillPreparationScopeRoot(home, WORKSPACE, 'codex');
|
|
111
|
+
await mkdir(root, { recursive: true, mode: 0o700 });
|
|
112
|
+
await chmod(root, 0o777);
|
|
113
|
+
await assert.rejects(withSkillPreparationTransaction({ home, workspaceId: WORKSPACE, provider: 'codex', assertCurrent: () => { } }, async () => { }), /private/);
|
|
114
|
+
assert.equal((await stat(root)).mode & 0o777, 0o777);
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
await rm(home, { recursive: true, force: true });
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
for (const interruption of ['normal release', 'process death']) {
|
|
121
|
+
test(`two-process preparation locking: ${interruption}`, { timeout: 20000 }, async (context) => {
|
|
122
|
+
const home = await mkdtemp(join(tmpdir(), 'af-preparation-process-'));
|
|
123
|
+
const moduleUrl = new URL('./skillPreparationTransaction.js', import.meta.url).href;
|
|
124
|
+
const script = `import { withSkillPreparationTransaction } from ${JSON.stringify(moduleUrl)};
|
|
125
|
+
await withSkillPreparationTransaction({home:process.argv[1], workspaceId:${JSON.stringify(WORKSPACE)},
|
|
126
|
+
provider:'codex', assertCurrent:()=>{}}, async()=>{
|
|
127
|
+
console.log('locked'); await new Promise(resolve=>process.stdin.once('data',resolve));
|
|
128
|
+
});`;
|
|
129
|
+
const child = spawn(process.execPath, ['--input-type=module', '-e', script, home], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
130
|
+
const abortChild = () => { if (child.exitCode === null && child.signalCode === null)
|
|
131
|
+
child.kill('SIGKILL'); };
|
|
132
|
+
context.signal.addEventListener('abort', abortChild, { once: true });
|
|
133
|
+
let stderr = '', output = '', timer;
|
|
134
|
+
child.stderr.on('data', bytes => { stderr += bytes.toString(); });
|
|
135
|
+
const exit = new Promise((resolveExit, reject) => { child.once('error', reject); child.once('exit', resolveExit); });
|
|
136
|
+
const locked = new Promise(resolveLock => child.stdout.on('data', bytes => {
|
|
137
|
+
output += bytes.toString();
|
|
138
|
+
if (output.includes('locked\n') || output.includes('locked\r\n'))
|
|
139
|
+
resolveLock();
|
|
140
|
+
}));
|
|
141
|
+
try {
|
|
142
|
+
await Promise.race([locked, exit.then(code => { throw new Error(`Child exited before lock: ${code}: ${stderr}`); }),
|
|
143
|
+
new Promise((_, reject) => { timer = setTimeout(() => reject(new Error('Child lock observation timed out.')), 10000); })]);
|
|
144
|
+
clearTimeout(timer);
|
|
145
|
+
const input = { home, workspaceId: WORKSPACE, provider: 'codex', assertCurrent: () => { } };
|
|
146
|
+
await assert.rejects(withSkillPreparationTransaction({ ...input, timeoutMs: 50 }, async () => { }), /not granted/);
|
|
147
|
+
if (interruption === 'process death')
|
|
148
|
+
child.kill('SIGKILL');
|
|
149
|
+
else
|
|
150
|
+
child.stdin.end('release\n');
|
|
151
|
+
const code = await exit;
|
|
152
|
+
if (interruption === 'normal release')
|
|
153
|
+
assert.equal(code, 0);
|
|
154
|
+
await withSkillPreparationTransaction(input, async () => { });
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
context.signal.removeEventListener('abort', abortChild);
|
|
158
|
+
clearTimeout(timer);
|
|
159
|
+
if (child.exitCode === null && child.signalCode === null)
|
|
160
|
+
child.kill('SIGKILL');
|
|
161
|
+
await exit.catch(() => { });
|
|
162
|
+
await rm(home, { recursive: true, force: true });
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
test('actual relay holds preparation transaction ownership through staging publication', async () => {
|
|
167
|
+
const source = await readFile(new URL('../src/index.ts', import.meta.url), 'utf8');
|
|
168
|
+
const relay = source.slice(source.indexOf('async function relayStart('), source.indexOf('export async function run('));
|
|
169
|
+
assert.match(relay, /await withSkillPreparationTransaction\(/);
|
|
170
|
+
assert.ok(relay.indexOf('await withSkillPreparationTransaction(') < relay.indexOf('await prepareSkillUpdate('));
|
|
171
|
+
assert.ok(relay.indexOf('await prepareSkillUpdate(') < relay.indexOf("'PREPARED.json'"));
|
|
172
|
+
});
|
|
173
|
+
test('preparation scope is domain separated and workspace/provider isolated', async () => {
|
|
174
|
+
const module = await import('./skillPreparationTransaction.js');
|
|
175
|
+
const a = module.skillPreparationScopeRoot('/synthetic/home', '11111111-1111-4111-8111-111111111111', 'codex');
|
|
176
|
+
assert.notEqual(a, module.skillPreparationScopeRoot('/synthetic/home', '22222222-2222-4222-8222-222222222222', 'codex'));
|
|
177
|
+
assert.notEqual(a, module.skillPreparationScopeRoot('/synthetic/home', '11111111-1111-4111-8111-111111111111', 'claude'));
|
|
178
|
+
assert.throws(() => module.skillPreparationScopeRoot('/synthetic/home', '../foreign', 'codex'));
|
|
179
|
+
assert.throws(() => module.skillPreparationScopeRoot('/synthetic/home', '11111111-1111-4111-8111-111111111111', 'unknown'));
|
|
180
|
+
});
|
|
181
|
+
//# sourceMappingURL=skillPreparationTransaction.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillPreparationTransaction.test.js","sourceRoot":"","sources":["../src/skillPreparationTransaction.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillSyncPolicy.test.d.ts","sourceRoot":"","sources":["../src/skillSyncPolicy.test.ts"],"names":[],"mappings":""}
|