contextos-agents 1.7.0 → 2.0.0-beta.3
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 +16 -50
- 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 +100 -104
- 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 +537 -112
- package/.agents/customization-dx.js +282 -0
- package/.agents/doctor.js +855 -66
- 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 +278 -64
- package/.agents/profiles.js +486 -51
- package/.agents/resolver/canonical-resolver.js +1348 -0
- package/.agents/resolver.js +50 -534
- package/.agents/rules/rule-catalog.js +525 -0
- 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/skills-index.json +6 -166
- package/.agents/stats.js +9 -9
- 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 +87 -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
package/.agents/watch.js
CHANGED
|
@@ -1,154 +1,404 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* .agents/watch.js
|
|
3
|
-
* ContextOS —
|
|
3
|
+
* ContextOS — Coalescing Watch Daemon & Continuous Context Sync Engine
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Implements the Milestone 8 watch specification:
|
|
6
|
+
* - Coalescing event queue (pendingReasons set) preventing dropped events during compilation
|
|
7
|
+
* - ProjectMutationLock integration to guarantee single-writer safety across parallel processes
|
|
8
|
+
* - Directory containment & exclusion of generated/transient paths (.agents/generated, .agents/.contextos)
|
|
9
|
+
* - Multi-scope surveillance: skills, plugins, profiles, resources, AGENTS.md, package.json
|
|
10
|
+
* - Recursive watcher fast-path with directory-tree polling fallback
|
|
11
|
+
* - Failure diagnostics persistence (.agents/.contextos/watch-error.json) preventing daemon crash
|
|
12
|
+
* - Dependency drift detection without mutating active profile automatically
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
'use strict';
|
|
13
16
|
|
|
14
17
|
const fs = require('fs');
|
|
15
18
|
const path = require('path');
|
|
16
|
-
const { execFileSync } = require('child_process');
|
|
17
19
|
const profiles = require('./profiles.js');
|
|
20
|
+
const {
|
|
21
|
+
ProjectMutationLock,
|
|
22
|
+
toPosix,
|
|
23
|
+
} = require('./filesystem/index.js');
|
|
24
|
+
|
|
25
|
+
const IGNORED_PREFIXES = [
|
|
26
|
+
'.agents/.contextos',
|
|
27
|
+
'.agents/generated',
|
|
28
|
+
'.git',
|
|
29
|
+
'node_modules',
|
|
30
|
+
'.cursor',
|
|
31
|
+
'.zed',
|
|
32
|
+
'.contextos',
|
|
33
|
+
];
|
|
18
34
|
|
|
19
35
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* @param {string} [projectDir=process.cwd()] - Target project directory
|
|
23
|
-
* @param {Object} [options={}] - Watcher configuration options
|
|
24
|
-
* @param {number} [options.debounceMs=300] - Debounce delay in milliseconds
|
|
25
|
-
* @param {Function} [options.onSync] - Callback after a sync event completes
|
|
26
|
-
* @param {boolean} [options.exitOnSigint=true] - Whether to register process exit handlers
|
|
27
|
-
* @returns {Object} Controller object with a `close()` method
|
|
36
|
+
* Determines whether a relative path should be ignored by the file watcher.
|
|
28
37
|
*/
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const skillsDir = path.join(agentsDir, 'core', 'skills');
|
|
33
|
-
const ctxPath = path.join(agentsDir, 'ctx.js');
|
|
38
|
+
function shouldIgnorePath(relPath) {
|
|
39
|
+
if (!relPath) return true;
|
|
40
|
+
const norm = toPosix(relPath).replace(/^\.\//, '');
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
for (const prefix of IGNORED_PREFIXES) {
|
|
43
|
+
if (norm === prefix || norm.startsWith(`${prefix}/`)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
// Ignore lockfiles and direct adapter outputs
|
|
49
|
+
if (norm.endsWith('contextos.lock.json') || norm.endsWith('lockfile.v2.json')) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (norm === '.aider.conf.yml' || norm === 'CONVENTIONS.md' || norm === '.cursorrules') {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (norm.endsWith('copilot-instructions.md')) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
40
58
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const watchers = [];
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
44
61
|
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
class CoalescingWatchDaemon {
|
|
63
|
+
constructor(projectDir = process.cwd(), options = {}) {
|
|
64
|
+
this.projectDir = path.resolve(projectDir);
|
|
65
|
+
this.debounceMs = typeof options.debounceMs === 'number' ? options.debounceMs : 250;
|
|
66
|
+
this.options = options;
|
|
67
|
+
this.pendingReasons = new Set();
|
|
68
|
+
this.isProcessing = false;
|
|
69
|
+
this.closed = false;
|
|
70
|
+
this.debounceTimer = null;
|
|
71
|
+
this.watchers = [];
|
|
72
|
+
this.lastStack = null;
|
|
73
|
+
this.errorLogPath = path.join(this.projectDir, '.agents', '.contextos', 'watch-error.json');
|
|
74
|
+
this.lock = new ProjectMutationLock(this.projectDir);
|
|
75
|
+
}
|
|
47
76
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Initializes watchers across all monitored directories and files.
|
|
79
|
+
*/
|
|
80
|
+
start() {
|
|
81
|
+
if (!this.options.silent) {
|
|
82
|
+
console.log('\n[ContextOS Watch] Initializing background continuous sync daemon...');
|
|
83
|
+
console.log(`[ContextOS Watch] Project directory: ${this.projectDir}`);
|
|
84
|
+
}
|
|
51
85
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
61
|
-
console.log(`[${time}] [OK] Skills exported to all agents (Gemini, Claude, Cursor, Copilot, Aider, Zed).`);
|
|
62
|
-
}
|
|
86
|
+
try {
|
|
87
|
+
this.lastStack = profiles.detectStack(this.projectDir);
|
|
88
|
+
if (!this.options.silent) {
|
|
89
|
+
console.log(`[ContextOS Watch] Initial stack: ${this.lastStack.detected.join(', ') || 'Generic JS'} (${this.lastStack.recommendedProfile})`);
|
|
90
|
+
}
|
|
91
|
+
} catch {
|
|
92
|
+
this.lastStack = { detected: [], recommendedProfile: 'default' };
|
|
93
|
+
}
|
|
63
94
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
95
|
+
// 1. Monitored directories
|
|
96
|
+
const watchDirs = [
|
|
97
|
+
path.join(this.projectDir, '.agents', 'core', 'skills'),
|
|
98
|
+
path.join(this.projectDir, '.agents', 'plugins'),
|
|
99
|
+
path.join(this.projectDir, '.agents', 'resources'),
|
|
100
|
+
path.join(this.projectDir, '.agents', 'profiles'),
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
for (const dir of watchDirs) {
|
|
104
|
+
if (fs.existsSync(dir)) {
|
|
105
|
+
this.watchDirectory(dir);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 2. Monitored individual files
|
|
110
|
+
const watchFiles = [
|
|
111
|
+
path.join(this.projectDir, '.agents', 'AGENTS.md'),
|
|
112
|
+
path.join(this.projectDir, 'package.json'),
|
|
113
|
+
];
|
|
114
|
+
|
|
115
|
+
for (const file of watchFiles) {
|
|
116
|
+
if (fs.existsSync(file)) {
|
|
117
|
+
this.watchFile(file);
|
|
71
118
|
}
|
|
72
|
-
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!this.options.silent) {
|
|
122
|
+
console.log('[ContextOS Watch] Watching for skill updates and dependency shifts. Press Ctrl+C to stop.\n');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (this.options.exitOnSigint !== false) {
|
|
126
|
+
const onExit = () => {
|
|
127
|
+
if (!this.options.silent) {
|
|
128
|
+
console.log('\n[ContextOS Watch] Stopping watcher daemon.');
|
|
129
|
+
}
|
|
130
|
+
this.close();
|
|
131
|
+
process.exit(0);
|
|
132
|
+
};
|
|
133
|
+
process.once('SIGINT', onExit);
|
|
134
|
+
process.once('SIGTERM', onExit);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return this;
|
|
73
138
|
}
|
|
74
139
|
|
|
75
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Watches a directory with recursive watching, falling back to tree scanning.
|
|
142
|
+
*/
|
|
143
|
+
watchDirectory(dirPath) {
|
|
76
144
|
try {
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
145
|
+
const watcher = fs.watch(dirPath, { recursive: true }, (eventType, filename) => {
|
|
146
|
+
if (!filename) return;
|
|
147
|
+
const relToProject = toPosix(path.relative(this.projectDir, path.join(dirPath, filename)));
|
|
148
|
+
if (shouldIgnorePath(relToProject)) return;
|
|
80
149
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
console.log(` Detected stack : ${currentStack.detected.join(', ')}`);
|
|
85
|
-
console.log(` Recommendation : Profile '${currentStack.recommendedProfile}'`);
|
|
86
|
-
console.log(` Run: contextos profile apply ${currentStack.recommendedProfile}\n`);
|
|
87
|
-
lastStack = currentStack;
|
|
88
|
-
|
|
89
|
-
if (typeof options.onSync === 'function') {
|
|
90
|
-
options.onSync({ type: 'stack_change', stack: currentStack });
|
|
150
|
+
const lower = filename.toLowerCase();
|
|
151
|
+
if (lower.endsWith('.md') || lower.endsWith('.yaml') || lower.endsWith('.yml') || lower.endsWith('.json')) {
|
|
152
|
+
this.triggerRecompile(relToProject);
|
|
91
153
|
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
154
|
+
});
|
|
155
|
+
this.watchers.push(watcher);
|
|
156
|
+
} catch (e) {
|
|
157
|
+
// Fallback: Watch subdirectories individually if recursive is unsupported
|
|
158
|
+
this.watchTreeFallback(dirPath);
|
|
95
159
|
}
|
|
96
160
|
}
|
|
97
161
|
|
|
98
|
-
|
|
99
|
-
|
|
162
|
+
/**
|
|
163
|
+
* Fallback for systems where recursive fs.watch is unavailable.
|
|
164
|
+
*/
|
|
165
|
+
watchTreeFallback(dirPath) {
|
|
100
166
|
try {
|
|
101
|
-
const
|
|
167
|
+
const watcher = fs.watch(dirPath, (eventType, filename) => {
|
|
102
168
|
if (!filename) return;
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
169
|
+
const full = path.join(dirPath, filename);
|
|
170
|
+
const relToProject = toPosix(path.relative(this.projectDir, full));
|
|
171
|
+
if (shouldIgnorePath(relToProject)) return;
|
|
172
|
+
this.triggerRecompile(relToProject);
|
|
173
|
+
});
|
|
174
|
+
this.watchers.push(watcher);
|
|
175
|
+
|
|
176
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
177
|
+
for (const entry of entries) {
|
|
178
|
+
if (entry.isDirectory()) {
|
|
179
|
+
const sub = path.join(dirPath, entry.name);
|
|
180
|
+
const rel = toPosix(path.relative(this.projectDir, sub));
|
|
181
|
+
if (!shouldIgnorePath(rel)) {
|
|
182
|
+
this.watchTreeFallback(sub);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
} catch {}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Watches an individual file (e.g. package.json or AGENTS.md).
|
|
191
|
+
*/
|
|
192
|
+
watchFile(filePath) {
|
|
193
|
+
try {
|
|
194
|
+
const watcher = fs.watch(filePath, () => {
|
|
195
|
+
const rel = toPosix(path.relative(this.projectDir, filePath));
|
|
196
|
+
if (path.basename(filePath) === 'package.json') {
|
|
197
|
+
this.checkStackChange();
|
|
198
|
+
} else {
|
|
199
|
+
this.triggerRecompile(rel);
|
|
106
200
|
}
|
|
107
201
|
});
|
|
108
|
-
watchers.push(
|
|
109
|
-
} catch
|
|
110
|
-
|
|
202
|
+
this.watchers.push(watcher);
|
|
203
|
+
} catch {}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Queues a change reason and schedules a coalesced compilation pass.
|
|
208
|
+
*/
|
|
209
|
+
triggerRecompile(sourceReason) {
|
|
210
|
+
if (this.closed) return;
|
|
211
|
+
if (sourceReason) {
|
|
212
|
+
this.pendingReasons.add(sourceReason);
|
|
111
213
|
}
|
|
214
|
+
|
|
215
|
+
if (this.debounceTimer) {
|
|
216
|
+
clearTimeout(this.debounceTimer);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
this.debounceTimer = setTimeout(() => {
|
|
220
|
+
this.processQueue();
|
|
221
|
+
}, this.debounceMs);
|
|
112
222
|
}
|
|
113
223
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
224
|
+
/**
|
|
225
|
+
* Processes the coalescing queue until empty.
|
|
226
|
+
*/
|
|
227
|
+
async processQueue() {
|
|
228
|
+
if (this.isProcessing || this.closed) return;
|
|
229
|
+
if (this.pendingReasons.size === 0) return;
|
|
230
|
+
|
|
231
|
+
this.isProcessing = true;
|
|
232
|
+
|
|
117
233
|
try {
|
|
118
|
-
|
|
119
|
-
|
|
234
|
+
while (this.pendingReasons.size > 0 && !this.closed) {
|
|
235
|
+
// Snapshot reasons and clear the queue for incoming events during export
|
|
236
|
+
const reasonsSnapshot = Array.from(this.pendingReasons);
|
|
237
|
+
this.pendingReasons.clear();
|
|
238
|
+
|
|
239
|
+
await this.executeSync(reasonsSnapshot);
|
|
240
|
+
}
|
|
241
|
+
} finally {
|
|
242
|
+
this.isProcessing = false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Performs an export pass with atomic ProjectMutationLock mutual exclusion.
|
|
248
|
+
*/
|
|
249
|
+
async executeSync(reasons) {
|
|
250
|
+
let lockToken = null;
|
|
251
|
+
try {
|
|
252
|
+
try {
|
|
253
|
+
lockToken = this.lock.acquire({ command: 'watch:sync' });
|
|
254
|
+
} catch (err) {
|
|
255
|
+
if (err.code === 'CTX_PROJECT_BUSY') {
|
|
256
|
+
if (!this.options.silent) {
|
|
257
|
+
console.log(`[ContextOS Watch] Project mutation lock is held by another process. Re-queuing changes...`);
|
|
258
|
+
}
|
|
259
|
+
for (const r of reasons) {
|
|
260
|
+
this.pendingReasons.add(r);
|
|
261
|
+
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
throw err;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const time = new Date().toLocaleTimeString();
|
|
268
|
+
if (!this.options.silent) {
|
|
269
|
+
console.log(`[${time}] [SYNC] Changes detected (${reasons.slice(0, 3).join(', ')}${reasons.length > 3 ? ` +${reasons.length - 3} more` : ''}). Recompiling adapters...`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const { renderAdapters, applyArtifacts } = require('./adapters/pure-compiler.js');
|
|
273
|
+
const rendered = renderAdapters(this.projectDir, 'all');
|
|
274
|
+
const result = applyArtifacts(this.projectDir, rendered.artifacts, {
|
|
275
|
+
command: 'watch',
|
|
276
|
+
lockToken,
|
|
277
|
+
context: rendered.context,
|
|
120
278
|
});
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
279
|
+
|
|
280
|
+
if (!this.options.silent) {
|
|
281
|
+
console.log(`[${time}] [OK] Skills exported cleanly (${result.appliedCount} files applied, tx: ${result.txId}).`);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Clear any prior failure diagnostic on successful compile
|
|
285
|
+
if (fs.existsSync(this.errorLogPath)) {
|
|
286
|
+
try {
|
|
287
|
+
fs.unlinkSync(this.errorLogPath);
|
|
288
|
+
} catch {}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (typeof this.options.onSync === 'function') {
|
|
292
|
+
this.options.onSync({ type: 'recompile', reasons, result });
|
|
293
|
+
}
|
|
294
|
+
} catch (err) {
|
|
295
|
+
this.saveFailureDiagnostics(reasons, err);
|
|
296
|
+
if (typeof this.options.onSync === 'function') {
|
|
297
|
+
this.options.onSync({ type: 'error', reasons, error: err });
|
|
298
|
+
}
|
|
299
|
+
} finally {
|
|
300
|
+
if (lockToken) {
|
|
301
|
+
try {
|
|
302
|
+
this.lock.release(lockToken);
|
|
303
|
+
} catch {}
|
|
304
|
+
}
|
|
124
305
|
}
|
|
125
306
|
}
|
|
126
307
|
|
|
127
|
-
|
|
308
|
+
/**
|
|
309
|
+
* Persists failure diagnostics without crashing the long-running daemon.
|
|
310
|
+
*/
|
|
311
|
+
saveFailureDiagnostics(reasons, error) {
|
|
312
|
+
try {
|
|
313
|
+
const dir = path.dirname(this.errorLogPath);
|
|
314
|
+
if (!fs.existsSync(dir)) {
|
|
315
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
316
|
+
}
|
|
128
317
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
318
|
+
const payload = {
|
|
319
|
+
timestamp: new Date().toISOString(),
|
|
320
|
+
reasons,
|
|
321
|
+
error: error.message,
|
|
322
|
+
stack: error.stack,
|
|
323
|
+
code: error.code || 'ERR_COMPILATION_FAILED',
|
|
324
|
+
};
|
|
325
|
+
fs.writeFileSync(this.errorLogPath, JSON.stringify(payload, null, 2), 'utf8');
|
|
326
|
+
if (!this.options.silent) {
|
|
327
|
+
console.error(`[WARN] Auto-recompile failed: ${error.message}`);
|
|
328
|
+
console.error(` Diagnostics saved to ${toPosix(path.relative(this.projectDir, this.errorLogPath))}`);
|
|
329
|
+
}
|
|
330
|
+
} catch {}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Checks for tech stack and dependency changes without automatically altering profiles.
|
|
335
|
+
*/
|
|
336
|
+
checkStackChange() {
|
|
337
|
+
try {
|
|
338
|
+
const currentStack = profiles.detectStack(this.projectDir);
|
|
339
|
+
const prevStr = (this.lastStack?.detected || []).slice().sort().join(',');
|
|
340
|
+
const currStr = (currentStack.detected || []).slice().sort().join(',');
|
|
341
|
+
|
|
342
|
+
if (prevStr !== currStr) {
|
|
343
|
+
const time = new Date().toLocaleTimeString();
|
|
344
|
+
if (!this.options.silent) {
|
|
345
|
+
console.log(`\n[${time}] [DETECT] Project dependencies changed!`);
|
|
346
|
+
console.log(` Detected stack : ${currentStack.detected.join(', ') || 'None'}`);
|
|
347
|
+
console.log(` Recommendation : Profile '${currentStack.recommendedProfile}'`);
|
|
348
|
+
console.log(` Run: contextos profile apply ${currentStack.recommendedProfile}\n`);
|
|
349
|
+
}
|
|
350
|
+
this.lastStack = currentStack;
|
|
351
|
+
|
|
352
|
+
if (typeof this.options.onSync === 'function') {
|
|
353
|
+
this.options.onSync({ type: 'stack_change', stack: currentStack });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
} catch {
|
|
357
|
+
// Ignore transient read errors during npm install / edits
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Closes all watchers and cleans up active timers.
|
|
363
|
+
*/
|
|
364
|
+
close() {
|
|
365
|
+
this.closed = true;
|
|
366
|
+
if (this.debounceTimer) {
|
|
367
|
+
clearTimeout(this.debounceTimer);
|
|
368
|
+
this.debounceTimer = null;
|
|
369
|
+
}
|
|
370
|
+
for (const watcher of this.watchers) {
|
|
132
371
|
try {
|
|
133
|
-
|
|
372
|
+
watcher.close();
|
|
134
373
|
} catch {}
|
|
135
374
|
}
|
|
375
|
+
this.watchers = [];
|
|
136
376
|
}
|
|
377
|
+
}
|
|
137
378
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
379
|
+
/**
|
|
380
|
+
* Public entrypoint for ContextOS watch daemon.
|
|
381
|
+
*
|
|
382
|
+
* @param {string} [projectDir=process.cwd()]
|
|
383
|
+
* @param {object} [options={}]
|
|
384
|
+
* @returns {object} Controller exposing close(), triggerRecompile(), and checkStackChange()
|
|
385
|
+
*/
|
|
386
|
+
function runWatch(projectDir = process.cwd(), options = {}) {
|
|
387
|
+
const daemon = new CoalescingWatchDaemon(projectDir, options);
|
|
388
|
+
daemon.start();
|
|
147
389
|
|
|
148
390
|
return {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
391
|
+
daemon,
|
|
392
|
+
close: () => daemon.close(),
|
|
393
|
+
triggerRecompile: (reason) => daemon.triggerRecompile(reason),
|
|
394
|
+
checkStackChange: () => daemon.checkStackChange(),
|
|
395
|
+
processQueue: () => daemon.processQueue(),
|
|
396
|
+
get pendingReasons() {
|
|
397
|
+
return daemon.pendingReasons;
|
|
398
|
+
},
|
|
399
|
+
get isProcessing() {
|
|
400
|
+
return daemon.isProcessing;
|
|
401
|
+
},
|
|
152
402
|
};
|
|
153
403
|
}
|
|
154
404
|
|
|
@@ -157,5 +407,7 @@ if (require.main === module) {
|
|
|
157
407
|
}
|
|
158
408
|
|
|
159
409
|
module.exports = {
|
|
410
|
+
CoalescingWatchDaemon,
|
|
160
411
|
runWatch,
|
|
412
|
+
shouldIgnorePath,
|
|
161
413
|
};
|