contextos-agents 1.7.0 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/AGENTS.md +1 -1
- package/.agents/adapters/aider/export.js +117 -99
- package/.agents/adapters/claude/export.js +68 -26
- package/.agents/adapters/copilot/export.js +90 -53
- package/.agents/adapters/cursor/export.js +80 -101
- package/.agents/adapters/drift-detector.js +196 -0
- package/.agents/adapters/gemini/export.js +76 -45
- package/.agents/adapters/pure-compiler.js +443 -0
- package/.agents/adapters/zed/export.js +104 -96
- package/.agents/compiled/registry.v2.json +504 -0
- package/.agents/compiled/registry.v2.sha256 +1 -0
- package/.agents/compiler/manifest-compiler.js +963 -0
- package/.agents/compiler/vendor/yaml.LICENSE.txt +13 -0
- package/.agents/compiler/vendor/yaml.SBOM.json +6 -0
- package/.agents/compiler/vendor/yaml.js +139 -0
- package/.agents/core/profiles/init.yaml +25 -0
- package/.agents/core/skills/context-manager/skill.yaml +3 -5
- package/.agents/core/skills/context-os/SKILL.md +3 -6
- package/.agents/core/skills/context-os/skill.yaml +3 -8
- package/.agents/core/skills/engineering-workflow/skill.yaml +1 -7
- package/.agents/core/skills/gemini-precision/skill.yaml +1 -6
- package/.agents/core/skills/gstack-roles/skill.yaml +3 -6
- package/.agents/core/skills/ponytail-mindset/skill.yaml +1 -7
- package/.agents/core/skills/security/skill.yaml +15 -3
- package/.agents/ctx.js +574 -111
- package/.agents/customization-dx.js +282 -0
- package/.agents/doctor.js +719 -64
- package/.agents/filesystem/index.js +71 -0
- package/.agents/filesystem/journaled-transaction.js +451 -0
- package/.agents/filesystem/lockfile-v2.js +275 -0
- package/.agents/filesystem/platform-hardening.js +222 -0
- package/.agents/filesystem/project-lock.js +218 -0
- package/.agents/filesystem/safe-path.js +256 -0
- package/.agents/generated/claude/skills/context-os/SKILL.md +1 -1
- package/.agents/generated/gemini/skills/context-os/SKILL.md +2 -2
- package/.agents/plugins/contextos/plugin.json +1 -1
- package/.agents/plugins.js +259 -60
- package/.agents/profiles.js +486 -51
- package/.agents/resolver.js +50 -534
- package/.agents/schemas/attestation.review.v1.json +111 -0
- package/.agents/schemas/attestation.verification.v1.json +85 -0
- package/.agents/schemas/lockfile.v2.schema.json +134 -0
- package/.agents/schemas/profile.v2.schema.json +114 -0
- package/.agents/schemas/runtime.thread.v1.json +192 -0
- package/.agents/schemas/skill.manifest.v2.json +177 -0
- package/.agents/schemas/verification.spec.v1.json +39 -0
- package/.agents/schemas/workspace.graph.schema.json +106 -0
- package/.agents/transaction-core/event-store.js +288 -0
- package/.agents/transaction-core/idempotency.js +129 -0
- package/.agents/transaction-core/ipc-lock.js +311 -0
- package/.agents/transaction-core/plugin-supply-chain-bundle.js +436 -0
- package/.agents/validate.js +44 -1
- package/.agents/watch.js +354 -102
- package/.agents/workspace/workspace-graph.js +778 -0
- package/README.md +59 -387
- package/benchmarks/v2/analysis/statistics.js +140 -0
- package/benchmarks/v2/analysis/stats.js +69 -0
- package/benchmarks/v2/arms/arm-definitions.js +79 -0
- package/benchmarks/v2/dataset.schema.json +34 -0
- package/benchmarks/v2/evaluators/index.js +25 -0
- package/benchmarks/v2/evaluators/verified-success.js +116 -0
- package/benchmarks/v2/harness/runner.js +88 -0
- package/benchmarks/v2/pilot-tasks.json +392 -0
- package/bin/commands/recover.js +88 -0
- package/bin/commands/update.js +80 -17
- package/bin/commands.js +62 -25
- package/bin/index.js +138 -81
- package/bin/lib/lockfile.js +5 -3
- package/bin/lib/safe-writer.js +34 -3
- package/package.json +85 -72
- package/registry.json +2 -2
- package/registry.v2.schema.json +86 -0
- package/.agents/core/profiles/backend.yaml +0 -47
- package/.agents/core/profiles/enterprise.yaml +0 -46
- package/.agents/core/profiles/frontend.yaml +0 -46
- package/.agents/core/profiles/hackathon.yaml +0 -45
- package/.agents/core/profiles/mvp.yaml +0 -44
- package/.agents/core/profiles/startup.yaml +0 -48
- package/.agents/core/skills/adapters/EXAMPLES.md +0 -19
- package/.agents/core/skills/adapters/SKILL.md +0 -105
- package/.agents/core/skills/adapters/TROUBLESHOOTING.md +0 -7
- package/.agents/core/skills/adapters/VALIDATION.json +0 -12
- package/.agents/core/skills/adapters/skill.yaml +0 -16
- package/.agents/core/skills/architecture-diagrams/SKILL.md +0 -108
- package/.agents/core/skills/architecture-diagrams/VALIDATION.json +0 -12
- package/.agents/core/skills/architecture-diagrams/skill.yaml +0 -12
- package/.agents/core/skills/brutalist-design/SKILL.md +0 -150
- package/.agents/core/skills/brutalist-design/VALIDATION.json +0 -12
- package/.agents/core/skills/brutalist-design/skill.yaml +0 -12
- package/.agents/core/skills/database/EXAMPLES.md +0 -74
- package/.agents/core/skills/database/SKILL.md +0 -101
- package/.agents/core/skills/database/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/database/VALIDATION.json +0 -11
- package/.agents/core/skills/database/skill.yaml +0 -31
- package/.agents/core/skills/ddd/EXAMPLES.md +0 -42
- package/.agents/core/skills/ddd/SKILL.md +0 -247
- package/.agents/core/skills/ddd/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ddd/VALIDATION.json +0 -12
- package/.agents/core/skills/ddd/ddd.md +0 -178
- package/.agents/core/skills/ddd/skill.yaml +0 -17
- package/.agents/core/skills/decisions/EXAMPLES.md +0 -35
- package/.agents/core/skills/decisions/SKILL.md +0 -90
- package/.agents/core/skills/decisions/TROUBLESHOOTING.md +0 -13
- package/.agents/core/skills/decisions/VALIDATION.json +0 -12
- package/.agents/core/skills/decisions/skill.yaml +0 -16
- package/.agents/core/skills/docker/EXAMPLES.md +0 -56
- package/.agents/core/skills/docker/SKILL.md +0 -63
- package/.agents/core/skills/docker/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/docker/VALIDATION.json +0 -11
- package/.agents/core/skills/docker/skill.yaml +0 -29
- package/.agents/core/skills/fastapi/EXAMPLES.md +0 -36
- package/.agents/core/skills/fastapi/SKILL.md +0 -148
- package/.agents/core/skills/fastapi/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/fastapi/VALIDATION.json +0 -12
- package/.agents/core/skills/fastapi/fastapi.md +0 -112
- package/.agents/core/skills/fastapi/skill.yaml +0 -17
- package/.agents/core/skills/generators/EXAMPLES.md +0 -19
- package/.agents/core/skills/generators/SKILL.md +0 -112
- package/.agents/core/skills/generators/TROUBLESHOOTING.md +0 -7
- package/.agents/core/skills/generators/VALIDATION.json +0 -12
- package/.agents/core/skills/generators/skill.yaml +0 -25
- package/.agents/core/skills/generators/templates/API.md +0 -77
- package/.agents/core/skills/generators/templates/ARCHITECTURE.md +0 -70
- package/.agents/core/skills/generators/templates/DATABASE.md +0 -42
- package/.agents/core/skills/generators/templates/DECISION.md +0 -46
- package/.agents/core/skills/generators/templates/PRD.md +0 -67
- package/.agents/core/skills/generators/templates/PROJECT_GRAPH.md +0 -56
- package/.agents/core/skills/generators/templates/ROADMAP.md +0 -51
- package/.agents/core/skills/generators/templates/TASKS.md +0 -43
- package/.agents/core/skills/generators/templates/UI.md +0 -73
- package/.agents/core/skills/graphify/EXAMPLES.md +0 -73
- package/.agents/core/skills/graphify/SKILL.md +0 -130
- package/.agents/core/skills/graphify/VALIDATION.json +0 -12
- package/.agents/core/skills/graphify/skill.yaml +0 -18
- package/.agents/core/skills/impeccable-design/EXAMPLES.md +0 -26
- package/.agents/core/skills/impeccable-design/SKILL.md +0 -201
- package/.agents/core/skills/impeccable-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/impeccable-design/VALIDATION.json +0 -12
- package/.agents/core/skills/impeccable-design/skill.yaml +0 -20
- package/.agents/core/skills/interview-me/SKILL.md +0 -97
- package/.agents/core/skills/interview-me/VALIDATION.json +0 -12
- package/.agents/core/skills/interview-me/skill.yaml +0 -12
- package/.agents/core/skills/microservices/EXAMPLES.md +0 -38
- package/.agents/core/skills/microservices/SKILL.md +0 -164
- package/.agents/core/skills/microservices/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/microservices/VALIDATION.json +0 -12
- package/.agents/core/skills/microservices/microservices.md +0 -119
- package/.agents/core/skills/microservices/skill.yaml +0 -17
- package/.agents/core/skills/minimalist-design/SKILL.md +0 -113
- package/.agents/core/skills/minimalist-design/VALIDATION.json +0 -12
- package/.agents/core/skills/minimalist-design/skill.yaml +0 -12
- package/.agents/core/skills/nestjs/EXAMPLES.md +0 -40
- package/.agents/core/skills/nestjs/SKILL.md +0 -139
- package/.agents/core/skills/nestjs/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/nestjs/VALIDATION.json +0 -12
- package/.agents/core/skills/nestjs/nestjs.md +0 -103
- package/.agents/core/skills/nestjs/skill.yaml +0 -17
- package/.agents/core/skills/nextjs/EXAMPLES.md +0 -40
- package/.agents/core/skills/nextjs/SKILL.md +0 -163
- package/.agents/core/skills/nextjs/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/nextjs/VALIDATION.json +0 -12
- package/.agents/core/skills/nextjs/nextjs.md +0 -67
- package/.agents/core/skills/nextjs/skill.yaml +0 -17
- package/.agents/core/skills/node/EXAMPLES.md +0 -80
- package/.agents/core/skills/node/SKILL.md +0 -128
- package/.agents/core/skills/node/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/node/VALIDATION.json +0 -12
- package/.agents/core/skills/node/node.md +0 -87
- package/.agents/core/skills/node/skill.yaml +0 -17
- package/.agents/core/skills/performance/EXAMPLES.md +0 -30
- package/.agents/core/skills/performance/SKILL.md +0 -75
- package/.agents/core/skills/performance/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/performance/VALIDATION.json +0 -12
- package/.agents/core/skills/performance/performance.md +0 -52
- package/.agents/core/skills/performance/skill.yaml +0 -17
- package/.agents/core/skills/react/EXAMPLES.md +0 -79
- package/.agents/core/skills/react/SKILL.md +0 -132
- package/.agents/core/skills/react/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/react/VALIDATION.json +0 -12
- package/.agents/core/skills/react/react.md +0 -93
- package/.agents/core/skills/react/skill.yaml +0 -17
- package/.agents/core/skills/react-best-practices/SKILL.md +0 -155
- package/.agents/core/skills/react-best-practices/VALIDATION.json +0 -12
- package/.agents/core/skills/react-best-practices/skill.yaml +0 -14
- package/.agents/core/skills/redesign-audit/SKILL.md +0 -117
- package/.agents/core/skills/redesign-audit/VALIDATION.json +0 -12
- package/.agents/core/skills/redesign-audit/skill.yaml +0 -12
- package/.agents/core/skills/soft-design/SKILL.md +0 -108
- package/.agents/core/skills/soft-design/VALIDATION.json +0 -12
- package/.agents/core/skills/soft-design/skill.yaml +0 -12
- package/.agents/core/skills/state-management/EXAMPLES.md +0 -56
- package/.agents/core/skills/state-management/SKILL.md +0 -48
- package/.agents/core/skills/state-management/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/state-management/VALIDATION.json +0 -11
- package/.agents/core/skills/state-management/skill.yaml +0 -28
- package/.agents/core/skills/subagent-orchestrator/SKILL.md +0 -117
- package/.agents/core/skills/subagent-orchestrator/VALIDATION.json +0 -12
- package/.agents/core/skills/subagent-orchestrator/skill.yaml +0 -12
- package/.agents/core/skills/system-design/EXAMPLES.md +0 -75
- package/.agents/core/skills/system-design/SKILL.md +0 -419
- package/.agents/core/skills/system-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/system-design/VALIDATION.json +0 -12
- package/.agents/core/skills/system-design/skill.yaml +0 -20
- package/.agents/core/skills/system-design/system-design.md +0 -112
- package/.agents/core/skills/testing/EXAMPLES.md +0 -71
- package/.agents/core/skills/testing/SKILL.md +0 -70
- package/.agents/core/skills/testing/TROUBLESHOOTING.md +0 -18
- package/.agents/core/skills/testing/VALIDATION.json +0 -11
- package/.agents/core/skills/testing/skill.yaml +0 -32
- package/.agents/core/skills/typescript/EXAMPLES.md +0 -64
- package/.agents/core/skills/typescript/SKILL.md +0 -112
- package/.agents/core/skills/typescript/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/typescript/VALIDATION.json +0 -12
- package/.agents/core/skills/typescript/skill.yaml +0 -17
- package/.agents/core/skills/typescript/typescript.md +0 -71
- package/.agents/core/skills/ui-design/EXAMPLES.md +0 -21
- package/.agents/core/skills/ui-design/SKILL.md +0 -124
- package/.agents/core/skills/ui-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ui-design/VALIDATION.json +0 -12
- package/.agents/core/skills/ui-design/skill.yaml +0 -17
- package/.agents/core/skills/ui-design/ui.md +0 -88
- package/.agents/core/skills/ui-ux-pro/EXAMPLES.md +0 -62
- package/.agents/core/skills/ui-ux-pro/SKILL.md +0 -375
- package/.agents/core/skills/ui-ux-pro/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ui-ux-pro/VALIDATION.json +0 -12
- package/.agents/core/skills/ui-ux-pro/skill.yaml +0 -19
- package/.agents/core/skills/ux-design/EXAMPLES.md +0 -36
- package/.agents/core/skills/ux-design/SKILL.md +0 -116
- package/.agents/core/skills/ux-design/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/ux-design/VALIDATION.json +0 -12
- package/.agents/core/skills/ux-design/skill.yaml +0 -17
- package/.agents/core/skills/ux-design/ux.md +0 -80
- package/.agents/core/skills/vercel-optimize/SKILL.md +0 -83
- package/.agents/core/skills/vercel-optimize/VALIDATION.json +0 -12
- package/.agents/core/skills/vercel-optimize/scripts/collect-signals.mjs +0 -131
- package/.agents/core/skills/vercel-optimize/scripts/gate-investigations.mjs +0 -142
- package/.agents/core/skills/vercel-optimize/scripts/merge-signals.mjs +0 -143
- package/.agents/core/skills/vercel-optimize/scripts/scan-codebase.mjs +0 -174
- package/.agents/core/skills/vercel-optimize/skill.yaml +0 -18
- package/.agents/core/skills/web-accessibility/EXAMPLES.md +0 -39
- package/.agents/core/skills/web-accessibility/SKILL.md +0 -170
- package/.agents/core/skills/web-accessibility/TROUBLESHOOTING.md +0 -19
- package/.agents/core/skills/web-accessibility/VALIDATION.json +0 -12
- package/.agents/core/skills/web-accessibility/accessibility.md +0 -63
- package/.agents/core/skills/web-accessibility/skill.yaml +0 -17
- package/.agents/generated/claude/skills/adapters/SKILL.md +0 -126
- package/.agents/generated/claude/skills/architecture-diagrams/SKILL.md +0 -101
- package/.agents/generated/claude/skills/brutalist-design/SKILL.md +0 -145
- package/.agents/generated/claude/skills/database/SKILL.md +0 -191
- package/.agents/generated/claude/skills/ddd/SKILL.md +0 -305
- package/.agents/generated/claude/skills/decisions/SKILL.md +0 -134
- package/.agents/generated/claude/skills/docker/SKILL.md +0 -135
- package/.agents/generated/claude/skills/fastapi/SKILL.md +0 -200
- package/.agents/generated/claude/skills/generators/SKILL.md +0 -133
- package/.agents/generated/claude/skills/graphify/SKILL.md +0 -198
- package/.agents/generated/claude/skills/impeccable-design/SKILL.md +0 -241
- package/.agents/generated/claude/skills/interview-me/SKILL.md +0 -90
- package/.agents/generated/claude/skills/microservices/SKILL.md +0 -218
- package/.agents/generated/claude/skills/minimalist-design/SKILL.md +0 -108
- package/.agents/generated/claude/skills/nestjs/SKILL.md +0 -195
- package/.agents/generated/claude/skills/nextjs/SKILL.md +0 -219
- package/.agents/generated/claude/skills/node/SKILL.md +0 -224
- package/.agents/generated/claude/skills/performance/SKILL.md +0 -121
- package/.agents/generated/claude/skills/react/SKILL.md +0 -227
- package/.agents/generated/claude/skills/react-best-practices/SKILL.md +0 -146
- package/.agents/generated/claude/skills/redesign-audit/SKILL.md +0 -112
- package/.agents/generated/claude/skills/soft-design/SKILL.md +0 -103
- package/.agents/generated/claude/skills/state-management/SKILL.md +0 -120
- package/.agents/generated/claude/skills/subagent-orchestrator/SKILL.md +0 -110
- package/.agents/generated/claude/skills/system-design/SKILL.md +0 -507
- package/.agents/generated/claude/skills/testing/SKILL.md +0 -157
- package/.agents/generated/claude/skills/typescript/SKILL.md +0 -192
- package/.agents/generated/claude/skills/ui-design/SKILL.md +0 -161
- package/.agents/generated/claude/skills/ui-ux-pro/SKILL.md +0 -451
- package/.agents/generated/claude/skills/ux-design/SKILL.md +0 -168
- package/.agents/generated/claude/skills/vercel-optimize/SKILL.md +0 -76
- package/.agents/generated/claude/skills/web-accessibility/SKILL.md +0 -225
- package/.agents/generated/gemini/skills/adapters/SKILL.md +0 -135
- package/.agents/generated/gemini/skills/architecture-diagrams/SKILL.md +0 -107
- package/.agents/generated/gemini/skills/brutalist-design/SKILL.md +0 -151
- package/.agents/generated/gemini/skills/database/SKILL.md +0 -200
- package/.agents/generated/gemini/skills/ddd/SKILL.md +0 -314
- package/.agents/generated/gemini/skills/decisions/SKILL.md +0 -143
- package/.agents/generated/gemini/skills/docker/SKILL.md +0 -144
- package/.agents/generated/gemini/skills/fastapi/SKILL.md +0 -209
- package/.agents/generated/gemini/skills/generators/SKILL.md +0 -142
- package/.agents/generated/gemini/skills/graphify/SKILL.md +0 -205
- package/.agents/generated/gemini/skills/impeccable-design/SKILL.md +0 -250
- package/.agents/generated/gemini/skills/interview-me/SKILL.md +0 -96
- package/.agents/generated/gemini/skills/microservices/SKILL.md +0 -227
- package/.agents/generated/gemini/skills/minimalist-design/SKILL.md +0 -114
- package/.agents/generated/gemini/skills/nestjs/SKILL.md +0 -204
- package/.agents/generated/gemini/skills/nextjs/SKILL.md +0 -298
- package/.agents/generated/gemini/skills/node/SKILL.md +0 -323
- package/.agents/generated/gemini/skills/performance/SKILL.md +0 -185
- package/.agents/generated/gemini/skills/react/SKILL.md +0 -332
- package/.agents/generated/gemini/skills/react-best-practices/SKILL.md +0 -152
- package/.agents/generated/gemini/skills/redesign-audit/SKILL.md +0 -118
- package/.agents/generated/gemini/skills/soft-design/SKILL.md +0 -109
- package/.agents/generated/gemini/skills/state-management/SKILL.md +0 -129
- package/.agents/generated/gemini/skills/subagent-orchestrator/SKILL.md +0 -116
- package/.agents/generated/gemini/skills/system-design/SKILL.md +0 -631
- package/.agents/generated/gemini/skills/testing/SKILL.md +0 -166
- package/.agents/generated/gemini/skills/typescript/SKILL.md +0 -275
- package/.agents/generated/gemini/skills/ui-design/SKILL.md +0 -170
- package/.agents/generated/gemini/skills/ui-ux-pro/SKILL.md +0 -460
- package/.agents/generated/gemini/skills/ux-design/SKILL.md +0 -177
- package/.agents/generated/gemini/skills/vercel-optimize/SKILL.md +0 -82
- package/.agents/generated/gemini/skills/web-accessibility/SKILL.md +0 -300
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .agents/filesystem/safe-path.js
|
|
3
|
+
* ContextOS Authoritative Safe Path Primitive
|
|
4
|
+
*
|
|
5
|
+
* Implements strict containment and security validation:
|
|
6
|
+
* - Prevents directory traversal attacks (..)
|
|
7
|
+
* - Rejects absolute, drive-qualified (C:\), and UNC (\\server\share) paths
|
|
8
|
+
* - Rejects NUL bytes and Alternate Data Streams (ADS)
|
|
9
|
+
* - Blocks Windows reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9)
|
|
10
|
+
* - Enforces parent directory containment via realpath to stop symlink/junction escapes
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { isNetworkOrUNCPath } = require('./platform-hardening.js');
|
|
16
|
+
|
|
17
|
+
const ERROR_CODES = {
|
|
18
|
+
OUTSIDE_PROJECT: 'CTX_PATH_OUTSIDE_PROJECT',
|
|
19
|
+
INVALID: 'CTX_PATH_INVALID',
|
|
20
|
+
RESERVED_DEVICE: 'CTX_PATH_RESERVED_DEVICE',
|
|
21
|
+
SYMLINK_ESCAPE: 'CTX_PATH_SYMLINK_ESCAPE',
|
|
22
|
+
UNSUPPORTED: 'UNSUPPORTED',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const WINDOWS_RESERVED_NAMES = new Set([
|
|
26
|
+
'CON', 'PRN', 'AUX', 'NUL',
|
|
27
|
+
'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',
|
|
28
|
+
'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',
|
|
29
|
+
]);
|
|
30
|
+
|
|
31
|
+
class SafePathError extends Error {
|
|
32
|
+
constructor(code, message, details = {}) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = 'SafePathError';
|
|
35
|
+
this.code = code;
|
|
36
|
+
this.details = details;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Normalizes any path to forward slashes.
|
|
42
|
+
*/
|
|
43
|
+
function toPosix(p) {
|
|
44
|
+
return p.replace(/\\/g, '/');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Checks if a string segment is a Windows reserved device name.
|
|
49
|
+
*/
|
|
50
|
+
function isReservedDeviceName(segment) {
|
|
51
|
+
if (!segment) return false;
|
|
52
|
+
// Match exact name or name with extension (e.g. CON, con.txt, aux.json)
|
|
53
|
+
const baseName = segment.split('.')[0].toUpperCase();
|
|
54
|
+
return WINDOWS_RESERVED_NAMES.has(baseName);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Resolves and strictly validates a relative path inside projectRoot.
|
|
59
|
+
*
|
|
60
|
+
* @param {string} projectRoot - Absolute or relative path to project root
|
|
61
|
+
* @param {string} relativePath - Target relative path within project
|
|
62
|
+
* @param {object} [options]
|
|
63
|
+
* @param {boolean} [options.allowEscape=false] - If true, permits target outside root (default false)
|
|
64
|
+
* @param {boolean} [options.checkRealpathAncestors=true] - Verify ancestors do not symlink out of root
|
|
65
|
+
* @returns {{ resolvedPath: string, relativePosixPath: string }}
|
|
66
|
+
*/
|
|
67
|
+
function resolveManagedPath(projectRoot, relativePath, options = {}) {
|
|
68
|
+
const { checkRealpathAncestors = true } = options;
|
|
69
|
+
|
|
70
|
+
if (typeof projectRoot !== 'string' || projectRoot.trim() === '') {
|
|
71
|
+
throw new SafePathError(
|
|
72
|
+
ERROR_CODES.INVALID,
|
|
73
|
+
'Invalid project root: must be a non-empty string',
|
|
74
|
+
{ projectRoot }
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (typeof relativePath !== 'string' || relativePath.trim() === '') {
|
|
79
|
+
throw new SafePathError(
|
|
80
|
+
ERROR_CODES.INVALID,
|
|
81
|
+
'Invalid path: target relativePath must be a non-empty string',
|
|
82
|
+
{ relativePath }
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Check UNC/network path on project root
|
|
87
|
+
if (isNetworkOrUNCPath(projectRoot)) {
|
|
88
|
+
throw new SafePathError(
|
|
89
|
+
ERROR_CODES.UNSUPPORTED,
|
|
90
|
+
`UNC/network filesystem mutation is unsupported for projectRoot: ${projectRoot}`,
|
|
91
|
+
{ projectRoot, status: 'UNSUPPORTED' }
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 1. Check for NUL bytes
|
|
96
|
+
if (relativePath.includes('\0') || projectRoot.includes('\0')) {
|
|
97
|
+
throw new SafePathError(
|
|
98
|
+
ERROR_CODES.INVALID,
|
|
99
|
+
'Path contains forbidden NUL character',
|
|
100
|
+
{ relativePath }
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 2. Absolute, drive-qualified or UNC path checks (OUTSIDE_PROJECT)
|
|
105
|
+
if (/^[a-zA-Z]:[\\/]/.test(relativePath) || /^[a-zA-Z]:/.test(relativePath)) {
|
|
106
|
+
throw new SafePathError(
|
|
107
|
+
ERROR_CODES.OUTSIDE_PROJECT,
|
|
108
|
+
`Drive-qualified paths are forbidden: ${relativePath}`,
|
|
109
|
+
{ relativePath }
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (path.isAbsolute(relativePath)) {
|
|
114
|
+
throw new SafePathError(
|
|
115
|
+
ERROR_CODES.OUTSIDE_PROJECT,
|
|
116
|
+
`Path must be relative to project root, received absolute path: ${relativePath}`,
|
|
117
|
+
{ relativePath }
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (relativePath.startsWith('\\\\') || relativePath.startsWith('//')) {
|
|
122
|
+
throw new SafePathError(
|
|
123
|
+
ERROR_CODES.OUTSIDE_PROJECT,
|
|
124
|
+
`UNC network paths are forbidden: ${relativePath}`,
|
|
125
|
+
{ relativePath }
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 3. Alternate Data Streams (ADS) colon check
|
|
130
|
+
// On Windows, 'file.txt:stream' or 'file.txt::$DATA' accesses alternate streams
|
|
131
|
+
if (relativePath.includes(':')) {
|
|
132
|
+
throw new SafePathError(
|
|
133
|
+
ERROR_CODES.INVALID,
|
|
134
|
+
'Path contains forbidden Alternate Data Stream character (":")',
|
|
135
|
+
{ relativePath }
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 5. Windows reserved device names check
|
|
140
|
+
const normalizedSegments = toPosix(relativePath).split('/').filter(Boolean);
|
|
141
|
+
for (const seg of normalizedSegments) {
|
|
142
|
+
if (isReservedDeviceName(seg)) {
|
|
143
|
+
throw new SafePathError(
|
|
144
|
+
ERROR_CODES.RESERVED_DEVICE,
|
|
145
|
+
`Path segment '${seg}' is a reserved Windows device name (${Array.from(WINDOWS_RESERVED_NAMES).slice(0, 4).join(', ')}...)`,
|
|
146
|
+
{ segment: seg, relativePath }
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Resolve absolute project root
|
|
152
|
+
const absRoot = path.resolve(projectRoot);
|
|
153
|
+
const targetResolved = path.resolve(absRoot, relativePath);
|
|
154
|
+
|
|
155
|
+
// 6. Strict directory traversal & containment check
|
|
156
|
+
const relFromRoot = path.relative(absRoot, targetResolved);
|
|
157
|
+
if (relFromRoot.startsWith('..') || path.isAbsolute(relFromRoot) || relFromRoot === '') {
|
|
158
|
+
if (relFromRoot === '') {
|
|
159
|
+
throw new SafePathError(
|
|
160
|
+
ERROR_CODES.INVALID,
|
|
161
|
+
'Managed path cannot target the project root itself directly',
|
|
162
|
+
{ relativePath }
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
throw new SafePathError(
|
|
166
|
+
ERROR_CODES.OUTSIDE_PROJECT,
|
|
167
|
+
`Path '${relativePath}' resolves outside of project root '${absRoot}'`,
|
|
168
|
+
{ relativePath, targetResolved, absRoot }
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 7. Symlink / Junction escape check on existing ancestor directories
|
|
173
|
+
if (checkRealpathAncestors) {
|
|
174
|
+
let realRoot = absRoot;
|
|
175
|
+
try {
|
|
176
|
+
if (fs.existsSync(absRoot)) {
|
|
177
|
+
realRoot = fs.realpathSync(absRoot);
|
|
178
|
+
}
|
|
179
|
+
} catch {
|
|
180
|
+
// Best-effort if root realpath fails
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Traverse upwards from target to find the nearest existing directory
|
|
184
|
+
let currentDir = targetResolved;
|
|
185
|
+
while (currentDir && currentDir !== path.dirname(currentDir)) {
|
|
186
|
+
if (fs.existsSync(currentDir)) {
|
|
187
|
+
try {
|
|
188
|
+
const realAncestor = fs.realpathSync(currentDir);
|
|
189
|
+
const relFromRealRoot = path.relative(realRoot, realAncestor);
|
|
190
|
+
if (relFromRealRoot.startsWith('..') || path.isAbsolute(relFromRealRoot)) {
|
|
191
|
+
throw new SafePathError(
|
|
192
|
+
ERROR_CODES.SYMLINK_ESCAPE,
|
|
193
|
+
`Path ancestor '${currentDir}' resolves via symlink to '${realAncestor}' outside project realpath root '${realRoot}'`,
|
|
194
|
+
{ currentDir, realAncestor, realRoot }
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
} catch (err) {
|
|
198
|
+
if (err instanceof SafePathError) throw err;
|
|
199
|
+
// Ignore transient read errors for non-existent virtual paths
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
currentDir = path.dirname(currentDir);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const relativePosixPath = toPosix(relFromRoot);
|
|
208
|
+
|
|
209
|
+
return {
|
|
210
|
+
resolvedPath: targetResolved,
|
|
211
|
+
relativePosixPath,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Windows-aware atomic rename with bounded retry for transient locks (EPERM, EBUSY, EACCES).
|
|
217
|
+
*/
|
|
218
|
+
function safeRenameSync(sourcePath, targetPath, maxRetries = 4, delays = [10, 50, 150, 300]) {
|
|
219
|
+
const targetDir = path.dirname(targetPath);
|
|
220
|
+
if (!fs.existsSync(targetDir)) {
|
|
221
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let lastError = null;
|
|
225
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
226
|
+
try {
|
|
227
|
+
fs.renameSync(sourcePath, targetPath);
|
|
228
|
+
return;
|
|
229
|
+
} catch (err) {
|
|
230
|
+
lastError = err;
|
|
231
|
+
const isTransient = err.code === 'EPERM' || err.code === 'EBUSY' || err.code === 'EACCES';
|
|
232
|
+
if (isTransient && attempt < maxRetries) {
|
|
233
|
+
const waitMs = delays[attempt] || 50;
|
|
234
|
+
try {
|
|
235
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, waitMs);
|
|
236
|
+
} catch {
|
|
237
|
+
const start = Date.now();
|
|
238
|
+
while (Date.now() - start < waitMs) {}
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
throw lastError;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
module.exports = {
|
|
249
|
+
resolveManagedPath,
|
|
250
|
+
toPosix,
|
|
251
|
+
isReservedDeviceName,
|
|
252
|
+
safeRenameSync,
|
|
253
|
+
SafePathError,
|
|
254
|
+
ERROR_CODES,
|
|
255
|
+
WINDOWS_RESERVED_NAMES,
|
|
256
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Deterministic context compiler and policy engine for AI coding agents. Standardizes software engineering workflows across requirements, architecture, atomic task planning, implementation, verification, and release.
|
|
6
6
|
|
|
7
7
|
## When to Use
|
|
8
8
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: context-os
|
|
3
3
|
description: >
|
|
4
|
-
|
|
4
|
+
Deterministic context compiler and policy engine for AI coding agents.
|
|
5
5
|
---
|
|
6
6
|
# context-os
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Deterministic context compiler and policy engine for AI coding agents. Standardizes software engineering workflows across requirements, architecture, atomic task planning, implementation, verification, and release.
|
|
11
11
|
|
|
12
12
|
## When to Use
|
|
13
13
|
|